bzoj 1050 [HAOI2006]旅行comf——kruscal
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1050
因为还有Impossible的情况,所以想到了kruscal。(?)
但好像不太行。然后一直没思路。
然后想到因为一共5000条边,可以m^2枚举比值。枚举到一个比值其实就是限制能连的边是那两条边之间的边。
经Zinn提醒得知不用枚举两条边,枚举一条即可。
为什么自己的程序那么慢?
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N=505,M=5005; int n,m,fa[N],s,t,ans=30005,bns=1; struct Ed{ int x,y,w; bool operator< (const Ed &b)const {return w<b.w;} }ed[M]; int find(int a){return fa[a]==a?a:find(fa[a]);} int gcd(int a,int b){return b?gcd(b,a%b):a;} int main() { scanf("%d%d",&n,&m);int x,y,z; for(int i=1;i<=m;i++) scanf("%d%d%d",&ed[i].x,&ed[i].y,&ed[i].w); scanf("%d%d",&s,&t); sort(ed+1,ed+m+1); for(int i=1;i<=m;i++) { for(int j=1;j<=n;j++)fa[j]=j; for(int j=i;j<=m;j++) { if(find(ed[j].x)!=find(ed[j].y))fa[find(ed[j].x)]=find(ed[j].y); if(find(s)==find(t)) { if((double)ed[j].w/ed[i].w<(double)ans/bns) ans=ed[j].w,bns=ed[i].w; break; } } } if(ans==30005)puts("IMPOSSIBLE"); else if(ans%bns==0)printf("%d\n",ans/bns); else { int g=gcd(ans,bns);printf("%d/%d\n",ans/g,bns/g); } return 0; }