链接 :http://poj.org/problem?id=1797
题意一开始不太明确,题目是要求找一条链接1——n的一条路,这条路满足权值最大,因为是承载重量要选择,这条权值最大路径中某边的最小权值。当我们按照最大权值生成树构造完毕的时候,肯定任意两点间都有最大权值路径,也就意味着在构造过程中,每次从大到小添加边的时候,添加一旦发现出现了链接1——n的某条路径,那么break,记录下添加的最后一条边,即为所求。
#include<iostream> #include<algorithm> #include<string.h> using namespace std; const int INF=1005; int F[INF]; int r[INF]; int res; struct Edge { int u,v,weight; } per[1000005]; bool cmp(Edge a , Edge b) { return a.weight>b.weight; } int Find(int x) { if(x!=F[x]) F[x]=Find(F[x]); return F[x]; } //int Find(int x) //{ // int r=x; // while(r!=F[r]) // { // r=F[r]; // } // int k=x; // // while(k!=r) // { // int t=F[k]; // F[k]=r; // k=t; // } // return r; //} void init(int n) { for(int i=1; i<=n; i++) { F[i]=i; r[i]=1; } } void union_set(int u,int v) { int tx=Find(u); int ty=Find(v); if(tx==ty) return ; else if(r[tx]>r[ty]) F[ty]=tx; else if(r[tx]<r[ty]) F[tx]=ty; else { F[tx]=ty; r[ty]++; } } int main() { int t; cin>>t; int cas=1; while(t--) { int n,m,res=0; cin>>n>>m; init(n); for(int i=0; i<m; i++) { cin>>per[i].u>>per[i].v>>per[i].weight; } sort(per,per+m,cmp); for(int j=0; j<m; j++) { if(Find(1)==Find(n)) break; if(Find(per[j].u)!=Find(per[j].v)) { union_set(per[j].u,per[j].v); res=per[j].weight; } } cout<<"Scenario #"<<cas++<<":\n"<<res<<endl<<endl; } return 0; } /* 3 3 1 2 3 1 3 1 2 3 5 */
原文地址:http://blog.csdn.net/lsgqjh/article/details/46228205