POJ 1797

题目大意:
雨果—何伟十分的开心,在击败Cargolifter项目后他已能继续扩展业务了。但是,他需要一个聪明而机智的人来告诉他是否存在一个可以让他的客户从已建造的巨型起重机到目的地上的所有道路都可以承受重量。
庆幸的是,他已有一个方案关于所有的街道和桥梁允许的重量。不幸的是,他没有主意来找到最重的方案。但你一定能。

问题:
你被给与城市的方案,其中有路口间的道路(重量限制),被从1-n标号。你的目标是找到最大的路径从1(雨果的位置)到n(客户的位置)。你或许可以假设至少存在一条路径。所有路径是双向的。

输入

第一行是城市规划方案数。每组数据第一行是路口数(1<=n<=1000)并且街道数m也放到了第一行。下边的m行是两端和最大重量,<=1000000。两个路口间最大有一条边。

输出

见样例

Sample Input

1
3 3
1 2 3
1 3 4
2 3 5
Sample Output

Scenario #1:
4
warning!!!!!!
{
每组数据留一个空行!!!!!!!!!!
}

思路:
1.Dijkstra 改一点儿
2.Kruskal 改一点儿

#include <queue>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int map[1005][1005],cases,n,m;
bool vis[1005];
struct node
{
    int n,weight;
    friend bool operator<(node a,node b)
    {
        return a.weight<b.weight;
    }
}d[1005];
void dijkstra()
{
    for(int i=1;i<=n;i++)
    {
        d[i].n=i;
        d[i].weight=0;
    }
    d[1].weight=0x3ffffff;
    priority_queue<node> pq;
    pq.push(d[1]);
    while(!pq.empty())
    {
        node t=pq.top();pq.pop();
        int u=t.n;
        if(vis[u])continue;
        vis[u]=1;
        for(int i=1;i<=n;i++)
        {
            if(!vis[i]&&d[i].weight<min(map[u][i],d[u].weight)&&map[u][i]!=0)
                d[i].weight=min(map[u][i],d[u].weight),pq.push(d[i]);
        }
    }
}
int main()
{
    scanf("%d",&cases);
    for(int ii=1;ii<=cases;ii++)
    {
        memset(map,0,sizeof(map));
        memset(vis,0,sizeof(vis));
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++)
        {
            int a,b,c;
            scanf("%d%d%d",&a,&b,&c);
            map[a][b]=map[b][a]=c;
        }
        dijkstra();
        printf("Scenario #%d:
%d

",ii,d[n].weight);
    }
} 
#include <vector>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int f[1005],maxx,n,m,cas;
struct node
{
    int from,to,weight;
}d[1000005];
bool cmp(const node &a,const node &b)
{
    return a.weight>b.weight;
}
int find(int x)
{
    return x==f[x]?x:f[x]=find(f[x]);
}
void Kruskal()
{
    sort(d,d+m,cmp);
    for(int i=0;i<m;i++)
    {
//      printf("%d  %d  %d
",d[i].from,d[i].to,d[i].weight);
        int q=find(d[i].from),w=find(d[i].to);
        if(q!=w)
        {
            f[q]=w;
            maxx=min(maxx,d[i].weight);
            if(find(1)==find(n))
            break;
        }
    }
}
int main()
{
    scanf("%d",&cas);
    for(int ii=1;ii<=cas;ii++)
    {
        maxx=0x3fffffff;
        scanf("%d%d",&n,&m);
        for(int i=0;i<m;i++)
        {
            scanf("%d%d%d",&d[i].from,&d[i].to,&d[i].weight);
        }
        for(int i=1;i<=n;i++)f[i]=i;
        Kruskal();
        printf("Scenario #%d:
%d

",ii,maxx);
    }
}

这里写图片描述
最大生成树还是要快一点点的。。。

原文地址:https://www.cnblogs.com/SiriusRen/p/6532495.html