您的位置:首页 > 其它

hdu 1598 find the most comfortable road 枚举+并查集+贪心(类似最小生成树) ★★★

2015-12-08 13:46 323 查看


find the most comfortable road

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 5496    Accepted Submission(s): 2368


Problem Description

XX星有许多城市,城市之间通过一种奇怪的高速公路SARS(Super Air Roam Structure---超级空中漫游结构)进行交流,每条SARS都对行驶在上面的Flycar限制了固定的Speed,同时XX星人对 Flycar的“舒适度”有特殊要求,即乘坐过程中最高速度与最低速度的差越小乘坐越舒服 ,(理解为SARS的限速要求,flycar必须瞬间提速/降速,痛苦呀 ),

但XX星人对时间却没那么多要求。要你找出一条城市间的最舒适的路径。(SARS是双向的)。

 

Input

输入包括多个测试实例,每个实例包括:

第一行有2个正整数n (1<n<=200)和m (m<=1000),表示有N个城市和M条SARS。

接下来的行是三个正整数StartCity,EndCity,speed,表示从表面上看StartCity到EndCity,限速为speedSARS。speed<=1000000

然后是一个正整数Q(Q<11),表示寻路的个数。

接下来Q行每行有2个正整数Start,End, 表示寻路的起终点。

 

Output

每个寻路要求打印一行,仅输出一个非负整数表示最佳路线的舒适度最高速与最低速的差。如果起点和终点不能到达,那么输出-1。

 

Sample Input

4 4
1 2 2
2 3 4
1 4 1
3 4 2
2
1 3
1 2

 

Sample Output

1
0

 

Author

ailyanlu

 

Source

HDU 2007-Spring Programming Contest - Warm
Up (1)

 

Recommend

8600   |   We have carefully selected several similar problems for you:  1596 1217 1142 1385 1690 

 

这个题还是很有意思的,不是任何一种现成的算法。

对于这种规模算不上中等的题目,枚举是可以考虑的选择之一,枚举最容易被人忽视,当然还有动态规划,dfs啊。

规模较大,就要考虑一般的算法,比如图算法啊,数据结构啊,代表是O(nlogn),还有阀值,

对于规模特别大的题目,可能实际运算量非常小,也要考虑贪心。

题目说求的是s,t两点某条通路上的min{maxe-mine},

首先可以枚举mine,就是枚举权值最小的那条边,然后逐渐加入更大的边,直到s、t连通或者边用完为止。(这个贪心是很显然的)

题目之说了要求值,没有要你输出路径,也只说了求最大最小,唯一的条件就是s、t连通,要充分利用这些东西,只求最大,最小,

那边的数量我们就不用管。反正只要能判断是否连通即可。

#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<climits>
#include<queue>
#include<vector>
#include<map>
#include<sstream>
#include<set>
#include<stack>
#include<cctype>
#include<utility>
#pragma comment(linker, "/STACK:102400000,102400000")
#define PI (4.0*atan(1.0))
#define eps 1e-10
#define sqr(x) ((x)*(x))
#define FOR0(i,n) for(int i=0 ;i<(n) ;i++)
#define FOR1(i,n) for(int i=1 ;i<=(n) ;i++)
#define FORD(i,n) for(int i=(n) ;i>=0 ;i--)
#define lson ind<<1,le,mid
#define rson ind<<1|1,mid+1,ri
#define MID int mid=(le+ri)>>1
#define zero(x)((x>0? x:-x)<1e-15)
#define mk make_pair
#define _f first
#define _s second
using namespace std;
//const int INF= ;
typedef long long ll;
//const ll inf =1000000000000000;//1e15;
//ifstream fin("input.txt");
//ofstream fout("output.txt");
//fin.close();
//fout.close();
//freopen("a.in","r",stdin);
//freopen("a.out","w",stdout);
const int INF =0x3f3f3f3f;
const int maxn= 200+10 ;
const int maxm= 1000+20 ;

int pre[maxn];
int n,m;
struct Edge
{
int s,t,w;
Edge(){}
Edge(int s,int t,int w):s(s),t(t),w(w){}
bool operator<(const Edge y)const
{
return w<y.w;
}

}edges[maxm];
void init()
{
for(int i=1;i<=n;i++) pre[i]=i;
}
int find(int x) {return x==pre[x]?x:pre[x]=find(pre[x]); }
void merge(int s,int t)
{
int x=find(s);
int y=find(t);
if(x==y) return;
pre[x]=y;
}
int main()
{
int x,y,w;
while(~scanf("%d%d",&n,&m))
{
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&x,&y,&w);
edges[i]=Edge(x,y,w);
}
sort(edges+1,edges+1+m);
int q;
scanf("%d",&q);
int st,ed;
while(q--)
{
scanf("%d%d",&st,&ed);
int ans=INF;

for(int i=1;i<=m;i++)
{
init();
for(int j=i;j<=m;j++)
{
int s=edges[j].s;
int t=edges[j].t;
merge(s,t);
if(find(st)==find(ed))
{
ans=min(ans,edges[j].w-edges[i].w);
break;
}
}
}
if(ans==INF) puts("-1");
else printf("%d\n",ans);
}

}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: