POJ 1797 Heavy Transportation

来源:互联网 发布:网络储存空间 编辑:程序博客网 时间:2024/06/06 02:50

题意:找一条从 1 到 n 的道路,使得这条道路的每段距离中的最小值最大。

思路:
利用dijkstra或是spfa的思想去解,dis[ x ]表示从 1 到达 x 的道路中,其道路段的最小值的最大值
利用Kruskal的思想,把每段道路的权值按照从大到小排序,然后依次加边直至 1 可达 n为止,此时这条路中最小直即为答案。

代码:
kruskal(最大生成树)
#include<iostream>#include<algorithm>#include<cstdio>#include<cstring>using namespace std;const int maxn = 1005;struct Edge{    int u,v,w;}edge[maxn*maxn/2];int fa[maxn]; bool cmp(Edge a,Edge b){    return a.w > b.w;} int find(int x){    return fa[x] == x?fa[x]:fa[x] = find(fa[x]);} void Union(int x,int y){    int fx = find(x),fy = find(y);    if (fx != fy)   fa[fx] = fy;} int main(){    int tcase;    scanf("%d",&tcase);    for (int t = 1;t <= tcase;t++)    {        int n,m,res = 0x3f3f3f3f;        scanf("%d%d",&n,&m);        for (int i = 0;i <= n;i++)   fa[i] = i;        for (int i = 0;i < m;i++)        {            scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].w);        }        sort(edge,edge + m,cmp);        for (int i = 0; i< m;i++)        {            Union(edge[i].u,edge[i].v);            if (find(1) == find(n))            {                res = edge[i].w;                break;            }        }        printf("Scenario #%d:\n",t);        printf("%d\n",res);        if (t != tcase) printf("\n");    }    return 0;}
代码:dijkstra
#include<iostream>#include<cstdio>#include<cstring>#include<queue>using namespace std;const int maxn = 1005;const int INF = 0x3f3f3f3f;struct Edge{    int u,v,w,nxt;    bool operator < (const Edge &a)const    {        return w < a.w;    }}edge[maxn*maxn];int tot = 0,head[maxn],dis[maxn];bool vis[maxn]; void addedge(int u,int v,int w){    edge[tot] = (Edge){u,v,w,head[u]    };    head[u] = tot++;} void dijkstra(int st,int n){    Edge p;    priority_queue<Edge>que;    memset(dis,0,sizeof(dis));    memset(vis,false,sizeof(vis));    p.v = st;    p.w = INF;    dis[st] = INF;    que.push(p);    while (!que.empty())    {        p = que.top();        que.pop();        int u = p.v;        if (vis[u]) continue;        vis[u] = true;        for (int i = head[u];~i;i = edge[i].nxt)        {            int v = edge[i].v,w = edge[i].w;            if (dis[v] < min(dis[u],w))            {                dis[v] = min(dis[u],w);                p.v = v,p.w = dis[v];                que.push(p);            }        }    }}  int main(){    int tcase;    scanf("%d",&tcase);    for (int t = 1;t <= tcase;t++)    {        int n,m,u,v,w;        memset(head,-1,sizeof(head));        scanf("%d%d",&n,&m);        for (int i = 0;i < m;i++)        {            scanf("%d%d%d",&u,&v,&w);            addedge(u,v,w);            addedge(v,u,w);        }        dijkstra(1,n);        printf("Scenario #%d:\n",t);        printf("%d\n",dis[n]);        if (t != tcase) printf("\n");    }    return 0;     }


代码:spfa
#include<iostream>#include<cstdio>#include<cstring>#include<queue>using namespace std;const int maxn = 1005;const int INF = 0x3f3f3f3f;struct Edge{    int u,v,w,nxt;}edge[maxn*maxn];int tot = 0,head[maxn],dis[maxn];bool vis[maxn]; void addedge(int u,int v,int w){    edge[tot] = (Edge){u,v,w,head[u]    };    head[u] = tot++;}  void spfa(int st,int ed){    memset(vis,false,sizeof(vis));    memset(dis,0,sizeof(dis));    queue<int>que;    dis[st] = INF;    que.push(st);    vis[st] = true;    while (!que.empty())    {        int u = que.front();        que.pop();        vis[u] = false;        for (int i = head[u];~i;i = edge[i].nxt)        {            int v = edge[i].v,w = edge[i].w;            if (min(dis[u],w) > dis[v])            {                dis[v] = min(dis[u],w);                if (!vis[v])                {                    que.push(v);                    vis[v] = true;                }            }        }    }} int main(){    int tcase;    scanf("%d",&tcase);    for (int t = 1;t <= tcase;t++)    {        int n,m,u,v,w;        memset(head,-1,sizeof(head));        scanf("%d%d",&n,&m);        for (int i = 0;i < m;i++)        {            scanf("%d%d%d",&u,&v,&w);            addedge(u,v,w);            addedge(v,u,w);        }        spfa(1,n);        printf("Scenario #%d:\n",t);        printf("%d\n",dis[n]);        if (t != tcase) printf("\n");    }}





原创粉丝点击