POJ P1797 Heavy Transportation

题目链接:http://poj.org/problem?id=1797

题目大意:已知城市规划(即各个交叉点之间的街道的权重限制),找到从1号交叉口到n号交叉口可以运输的最大重量。您可以假设至少有一条路径。所有街道均可双向行驶。

Idea:在一张无向图中找一条经过1到n点的路径,使得路径的权重最大。(因为路径权重最大找到路径中权值最小的街道即是1号交叉口到n号交叉口的可运输最大距离),形象的说就是找最大木桶的最短板。

既然是找点1到点n的权重最大路径,可以通过构建一颗最大生成树,当点1和点n相连时则找到了最大生成树的最小边

 

#include<iostream>
#include<cstdio>
#include<queue> 
#include<cmath>
#include<cstring>
#include<string>
#include<algorithm>
#define int long long
#define MAXN 1010
#define INF 0x7fffffff
using namespace  std;

inline int read()
{
    int cnt=0,flag=1;
    char ch=getchar();
    while(ch>'9'||ch<'0'){if(ch=='-') flag=-1;  ch=getchar();}
    while(ch<='9'&&ch>='0'){cnt=cnt*10+ch-'0';  ch=getchar();}
    return cnt*flag;
}
int t,n,m,tmp,pre[MAXN],dis[MAXN];
struct edge{
    int u,v,d;
}e[MAXN*MAXN];

bool cmp(edge x,edge y){return x.d>y.d;}

int find(int x){
    return x==pre[x]?x:pre[x]=find(pre[x]);
}

inline void init(){ for(int i=0;i<=n;i++) pre[i]=i;  tmp=0;}
//最大生成树 
inline void MBT(){
    t=read();  
    for(int j=1;j<=t;j++){
        int ans=INF;
        n=read();  m=read();
        init();
        for(int i=0;i<m;i++){
            e[i].u=read();  e[i].v=read();
            e[i].d=read();
        }
        sort(e,e+m,cmp);
        for(int i=0;i<m;i++){
            int fu=find(e[i].u);
            int fv=find(e[i].v);
            if(fu!=fv){
                pre[fv]=fu;
                dis[tmp++]=e[i].d;
                if(find(1)==find(n)){
                    ans=e[i].d;
                    break;
                }
            }
        }
        printf("Scenario #%lld:\n%d\n\n",j,ans);
    }
    return ;
}

signed main()
{
    MBT();
    return 0;
}

 

posted @ 2020-12-03 22:17  面向题目编程  阅读(84)  评论(0)    收藏  举报