POJ 1797 条件最大生成树

这题做的囧死,看了样例很兴奋的写了个dijkstra交上去WA,重新看了下题目,发现是每条路都有一个最大承载量,好吧,我又想错了,发现不是网络流,因为样例用最大流说不通,再仔细看了一遍题目,发现是叫你找一条路使得单条路的流量最大,果断写了个最大生成树,觉得最大生成树的最小边就是解,叫上去,再次WA。

 

想了一会儿才发现不对,如果有一条路流量很大,但是这条路建出来的时候生成树没有建好呢?后来在Kruskal函数里加了一句很重要的话,果断AC。。。。。

 

本题的思路就是求最大生成树,当1和n在一个集合里的时候就返回最小边权,这个边权就是解。

 

我的代码:

#include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> using namespace std; const int MAX=1100; const int oo=0x3f3f3f3f; struct Edge{ int u,v,len; bool operator<(const Edge& e) const{ return len>e.len; } void read(){ scanf("%d%d%d",&u,&v,&len); } }e[MAX*MAX]; int p[MAX],rank[MAX],n,m; void init(){ for(int i=1;i<=n;i++){ p[i]=i; rank[i]=0; } } int find(int x){ return p[x]=x==p[x]?p[x]:find(p[x]); } void Link(int x,int y){ if(rank[x]>rank[y]){ p[y]=x; }else{ p[x]=y; if(rank[x]==rank[y]){ rank[y]++; } } } bool merge(int x,int y){ int px=find(x); int py=find(y); if(px==py){ return false; } Link(px,py); return true; } int Kruskal(){ int ret=0; int cnt=1; init(); sort(e,e+m); for(int i=0;i<m&&cnt<n;i++){ if(merge(e[i].u,e[i].v)){ cnt++; ret=e[i].len; } if(find(1)==find(n)){ break; } } return ret; } int main(){ int t,cnt=1; bool done=false; scanf("%d",&t); while(t--){ if(done){ puts(""); }else{ done=true; } scanf("%d%d",&n,&m); for(int i=0;i<m;i++){ e[i].read(); } printf("Scenario #%d:/n",cnt++); printf("%d/n",Kruskal()); } return 0; }

 

你可能感兴趣的:(POJ 1797 条件最大生成树)