[BZOJ1050][HAOI2006]旅行comf 枚举+并查集

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1050

将边排序,枚举边权最小的边,依次加边直到S和T连通,更新答案。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 int inline readint(){
 6     int Num;char ch;
 7     while((ch=getchar())<'0'||ch>'9');Num=ch-'0';
 8     while((ch=getchar())>='0'&&ch<='9') Num=Num*10+ch-'0';
 9     return Num;
10 }
11 int N,M,S,T;
12 struct EDGE{
13     int u,v,w;
14     bool operator < (const EDGE &_)const{
15         return w<_.w;
16     }
17 }edge[5010];
18 int fa[510];
19 int inline Getfa(int x){
20     return fa[x]==x?x:fa[x]=Getfa(fa[x]);
21 }
22 int inline Gcd(int a,int b){
23     return !b?a:Gcd(b,a%b);
24 }
25 int main(){
26     N=readint();
27     M=readint();
28     for(int i=1;i<=M;i++){
29         edge[i].u=readint();
30         edge[i].v=readint();
31         edge[i].w=readint();
32     }
33     sort(edge+1,edge+1+M);
34     S=readint();
35     T=readint();
36     int ansu=30000,ansd=1;
37     for(int i=1;i<=M;i++){
38         for(int j=1;j<=N;j++) fa[j]=j;
39         int mx;
40         for(int j=i;j<=M;j++){
41             int fx=Getfa(edge[j].u),
42                 fy=Getfa(edge[j].v);
43             if(fx==fy) continue;
44             mx=edge[j].w;
45             fa[fx]=fy;
46             if(Getfa(S)==Getfa(T)) break;
47         }
48         if(Getfa(S)!=Getfa(T)) break;
49         if(mx*ansd<ansu*edge[i].w){
50             ansu=mx;
51             ansd=edge[i].w;
52         }
53     }
54     if(ansu==30000){
55         puts("IMPOSSIBLE");
56         return 0;
57     }
58     int gcd=Gcd(ansu,ansd);
59     ansu/=gcd;
60     ansd/=gcd;
61     if(ansd>1) printf("%d/%d\n",ansu,ansd);
62     else printf("%d\n",ansu);
63     return 0;
64 }

 

posted @ 2017-10-10 19:20  halfrot  阅读(53)  评论(0编辑  收藏