POJ 1797 Heavy Transportation(连通性问题)

来源:互联网 发布:域名访问出错升级中 编辑:程序博客网 时间:2024/04/29 03:40

题目:

http://poj.org/problem?id=1797

题意:

给出n个点,和m条点的路段,起始点为1,终点为n,求出起始点到终点 各条路径的最小路段 的最大值。

题解:

二分枚举所有边,判断起始和终点是否连通,复杂度为,m*lgm,m为图的边数

代码:

//求最大的每个路径段的最小值#include<stdio.h>#include<stdlib.h>#include<string>int T,N,M,Count;int map[1002][1002];int father[1001];int ans;struct load{int from;int to;int weight;};struct load G[500000];int cmp(const void*a,const void*b)//大到小排{struct load* c=(struct load*)a;struct load* d=(struct load*)b;return d->weight-c->weight;}void init(){int i;for(i=1;i<=N;i++) father[i]=i;}int find(int x){return father[x]=father[x]==x?x:find(father[x]);}int If_link(int x){init();ans=G[x].weight;//遍历所有边,大于ans的连通int i;for(i=0;i<Count;i++){if(G[i].weight>=ans){int fa1,fa2;fa1=find(G[i].from);fa2=find(G[i].to);if(fa1!=fa2) father[fa1]=fa2;}}if(find(1)==find(N)) return 1;else return 0;}int main(){scanf("%d",&T);int kase=1;while(T--){scanf("%d%d",&N,&M);int i,j;memset(map,63,sizeof(map));for(i=1;i<=M;i++){int sca1,sca2,sca3;scanf("%d%d%d",&sca1,&sca2,&sca3);if(map[sca1][sca2]>sca3){map[sca1][sca2]=map[sca2][sca1]=sca3;}}//转化成存边的图,好吧,习惯这么做Count=0;for(i=1;i<N;i++){for(j=i+1;j<=N;j++){if(map[i][j]!=map[1001][1001]){G[Count].from=i;G[Count].to=j;G[Count].weight=map[i][j];Count++;}}}qsort(G,Count,sizeof(G[0]),cmp);//从大到小排序//二分枚举int l=0,r=Count-1;while(1){if(r-l<=5) break;int mid=(l+r)/2;if(If_link(mid))//如果可以连通{r=mid;}else{l=mid+1;}}for(i=l;i<=r;i++){if(If_link(i)) break; }printf("Scenario #%d:\n",kase++);printf("%d\n\n",ans);}return 0;}


0 0