bzoj1050旅行
其实没有辣么难,
暴力枚举最小边是哪条边,然后每次跑一边最小生成树,
当$s,t$刚好联通时最后加的边的权值就是当前的最大边最小的情况
然后判断一下,更新答案就好
/************************************************************** Problem: 1050 User: zhangheran Language: C++ Result: Accepted Time:2656 ms Memory:2072 kb ****************************************************************/ #include<iostream> #include<cstdio> //#include"suqingnian.h" #include<algorithm> using namespace std; template<typename _Element_gcd> _Element_gcd _gcd(_Element_gcd _m, _Element_gcd _n) { while (_n != 0) { _Element_gcd _t = _m % _n; _m = _n; _n = _t; } return _m; } int n,m; struct data{ int u;int v;int value; friend bool operator <(const data &a,const data &b) {return a.value<b.value;} }edge[50010];int cnt; void add(int u,int v,int value) { edge[++cnt].u=u; edge[cnt].v=v; edge[cnt].value=value; return ; } int fa[50100]; inline void build() {for(int i=1;i<=n;i++) fa[i]=i;return ;} int find(const int &x) {return fa[x]==x?x:fa[x]=find(fa[x]); } inline bool check(const int &a,const int &b) {return find(a)==find(b);} inline void merge(const int &x,const int &y) {fa[fa[x]]=fa[y]; return ;} int u,v,value; int s,t;int ans1,ans2; int now1,now2,num; bool book=0;bool ins; int main() { scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) scanf("%d%d%d",&u,&v,&value),add(u,v,value); scanf("%d%d",&s,&t); sort(edge+1,edge+m+1); for(int i=1;i<=m;i++){ build();now1=edge[i].value;ins=false; for(int j=i;j<=m;j++) if(!check(edge[j].u,edge[j].v)){ merge(edge[j].u,edge[j].v); if(check(s,t)){now2=edge[j].value;book=true;ins=true;break;} } if(ins){ if(ans1==0||now1*ans2>ans1*now2) ans1=now1,ans2=now2; if(ans1!=0&&ans2!=0)num=_gcd(ans1,ans2),ans1/=num,ans2/=num;} } if(!book){puts("IMPOSSIBLE");return 0;} if(ans2==0) {puts("0");return 0;} num=_gcd(ans1,ans2); ans1/=num,ans2/=num; if(ans1==1) {printf("%d",ans2);return 0;} printf("%d/%d",ans2,ans1); return 0; }