[BZOJ1050]HAOI2007旅行|最小生成树|枚举

来源:互联网 发布:rebecca minkoff知乎 编辑:程序博客网 时间:2024/05/17 07:24

妈呀这题竟然是暴力。。先把边升序排序,然后从1-m枚举最小边i,从i开始往后向kruskal一样加边,第一个能使s,t联通的边就是以i为最小边的最优解,因为要尽量靠近嘛。。然后不断更新答案即可。。

#include<iostream>#include<cstdio>#include<memory.h>#include<algorithm>using namespace std;struct edge{int s,e,q;}ed[5005];int i,j,n,m,s,t,fs,ft,fz=30001,fm=1,fa[505];bool cmp(edge a,edge b){return a.q<b.q;}int gcd(int a,int b){return b==0? a:gcd(b,a%b);}int getfa(int x){return fa[x]==x? x:fa[x]=getfa(fa[x]);}void merge(int x,int y){int fx=getfa(x),fy=getfa(y);if (fx!=fy) fa[fx]=fy;}int main(){scanf("%d%d",&n,&m);for (i=1;i<=m;i++)scanf("%d%d%d",&ed[i].s,&ed[i].e,&ed[i].q);scanf("%d%d",&s,&t);sort(ed+1,ed+1+m,cmp);for (i=1;i<=m;i++){for (j=1;j<=n;j++) fa[j]=j;for (j=i;j<=m;j++){merge(ed[j].s,ed[j].e);if (getfa(s)==getfa(t)){if (fz*ed[i].q>fm*ed[j].q) fz=ed[j].q,fm=ed[i].q;break;}}}if (fm==1&&fz==30001) printf("IMPOSSIBLE");else{int d=gcd(fz,fm);fz/=d;fm/=d;if (fm==1) printf("%d\n",fz);else printf("%d/%d",fz,fm);}}


0 0
原创粉丝点击