[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 }