hdu 1598 (最小生成树+贪心)

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

思路:根据cruskal的思想,每次把最小的边加入到已选的集合里面。
一旦已选集合里出现了start和end,记录最大边与最小边的差值,那么就退出当前循环,然后更新ans。这就用到了贪心的思想。
注意在每次更新ans后都应该给father数组赋初值,因为下一轮的更新与当前的father数组无关。


 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstdlib>
 4 #include <algorithm>
 5 #include <cmath>
 6 #include <cstring>
 7 using namespace std;
 8 
 9 int const N=210;
10 const int INF=0x3f3f3f3f;
11 const int M=1010;
12 int father[N];
13 
14 struct node
15 {
16     int x,y;
17     int d;
18 };
19 
20 node a[M];
21 
22 int Find(int x)
23 {
24     int y=x;
25     while(y!=father[y]) y=father[y];
26     while(father[x]!=y)
27     {
28         int tmp=father[x];
29         father[x]=y;
30         x=tmp;
31     }
32     return y;
33 }
34 
35 void Union(int x,int y)
36 {
37     int fx=Find(x);
38     int fy=Find(y);
39     if(fx!=fy)
40         father[fx]=fy;
41 }
42 
43 bool cmp(node a,node b)
44 {
45     return a.d<b.d;
46 }
47 
48 int main()
49 {
50     int m,n;
51     while(~scanf("%d%d",&m,&n))
52     {
53         for(int i=0;i<n;i++)
54             scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].d);
55         sort(a,a+n,cmp);
56         int v;
57         scanf("%d",&v);
58         while(v--)
59         {
60             int s,e;
61             scanf("%d%d",&s,&e);
62             int ans=INF;
63             for(int i=0;i<n;i++)
64             {
65                 for(int k=1;k<=m;k++) father[k]=k;  //每次都给father数组赋初值
66                 int tmp=INF;
67                 for(int j=i;j<n;j++)
68                 {
69                     if(Find(a[j].x)!=Find(a[j].y))
70                     {
71                         Union(a[j].x,a[j].y);
72                         if(Find(s)==Find(e))     //一旦发现start和end在同一个集合里,则退出
73                         {
74                             tmp=a[j].d-a[i].d;
75                             //cout<<i<<" "<<j<<" tmp="<<tmp<<endl;
76                             break;
77                         }
78                     }
79                 }
80                 ans=min(ans,tmp);      //每次选出最舒适的那个速度差
81             }
82             if(ans==INF) printf("-1\n");      //起点和终点之间没有通路
83             else printf("%d\n",ans);
84         }
85     }
86     return 0;
87 }

 

posted @ 2016-08-05 19:54  lianyuAngel  Views(131)  Comments(0)    收藏  举报