1. 程式人生 > >[BZOJ1050][HAOI2006]旅行comf 枚舉+並查集

[BZOJ1050][HAOI2006]旅行comf 枚舉+並查集

const printf 枚舉 getc 依次 sin gcd for 排序

題目鏈接: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 }

[BZOJ1050][HAOI2006]旅行comf 枚舉+並查集