bzoj1050 [HAOI2006]旅行comf
kruskal最小生成树
将边排序
枚举起点加边,求出生成树更新答案即可
1 #include<algorithm> 2 #include<iostream> 3 #include<cstdlib> 4 #include<cstring> 5 #include<cstdio> 6 #include<string> 7 #include<cmath> 8 #include<ctime> 9 #include<queue> 10 #include<stack> 11 #include<map> 12 #include<set> 13 #define rre(i,r,l) for(int i=(r);i>=(l);i--) 14 #define re(i,l,r) for(int i=(l);i<=(r);i++) 15 #define Clear(a,b) memset(a,b,sizeof(a)) 16 #define douin(x) scanf("%lf",&x) 17 #define strin(x) scanf("%s",(x)) 18 #define LLin(x) scanf("%lld",&x) 19 #define inin(x) scanf("%d",&x) 20 #define CSC main 21 typedef unsigned long long ULL; 22 typedef const int cint; 23 typedef long long LL; 24 using namespace std; 25 cint M=5001,N=501,P=9999999; 26 int yp() 27 { 28 int x=0,f=0;char ch=getchar(); 29 while(ch<'0'||ch>'9'){if(ch=='-')f=1;ch=getchar();} 30 while(ch>='0'&&ch<='9')x*=10,x+=ch-'0',ch=getchar(); 31 return f?-x:x; 32 } 33 struct ra 34 { 35 int x,y; 36 double v; 37 }s[M]; 38 int fa[N],m,n,Max,Min,x,y,maxn,minn; 39 bool bo; 40 int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);} 41 int comp(ra a,ra b) 42 { 43 return a.v<b.v; 44 } 45 void merge(int x,int y) 46 { 47 int q=find(x),w=find(y); 48 if(q!=w)fa[q]=w; 49 } 50 int gcd(int a,int b) 51 { 52 int c; 53 while(a%b)c=a%b,a=b,b=c; 54 return b; 55 } 56 int CSC() 57 { 58 double f,total=P; 59 n=yp(),m=yp(); 60 re(i,1,n)fa[i]=i; 61 re(i,1,m) 62 { 63 s[i].x=yp(),s[i].y=yp(); 64 douin(s[i].v); 65 merge(s[i].x,s[i].y); 66 } 67 x=yp(),y=yp(); 68 if(find(x)!=find(y)){cout<<"IMPOSSIBLE";return 0;} 69 sort(s+1,s+m+1,comp); 70 re(i,1,m) 71 { 72 bo=0;maxn=s[i].v; 73 re(j,1,n)fa[j]=j; 74 merge(s[i].x,s[i].y); 75 rre(j,i,1) 76 { 77 f=s[i].v/s[j].v; 78 if(f>=total){bo=0;break;} 79 merge(s[j].x,s[j].y); 80 if(find(x)==find(y)) 81 { 82 minn=s[j].v; 83 bo=1; 84 break; 85 } 86 } 87 if(!bo)continue; 88 total=f; 89 Max=maxn;Min=minn; 90 } 91 if(Max%Min==0){printf("%d",Max/Min);return 0;} 92 int d=gcd(Max,Min); 93 Max/=d,Min/=d; 94 printf("%d/%d",Max,Min); 95 }