zoj 1456 Minimum Transport Cost 最短路

简介:

   书上把这放在了bellman,但我觉得用floyd应该更加好写些

    注意一个坑人的地方,就是测试数据中有自己到自己,输出是单独的n,而不是n-->n

/*
author:jxy
lang:C/C++
university:China,Xidian University
**If you need to reprint,please indicate the source**
*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <queue>
#define maxn 100
using namespace std;
int dis[maxn][maxn],p[maxn],n;
queue<int> q;
int d[maxn];
int near[maxn];
bool inq[maxn];
int way[2][maxn],K[2];
void path(int now,bool f)
{
    if(near[now]==now)return;
    else
    {
        path(near[now],f);
        way[f][K[f]++]=now;
    }
}
bool cmp(int a,int b,int c)//生成路径比较字典序大小
{
    K[0]=K[1]=0;
    path(a,0);
    path(b,1);
    way[0][K[0]++]=c;
    way[1][K[1]++]=c;
    int i;
    for(i=0;way[0][i]+way[1][i];i++)
    {
        if(way[0][i]>way[1][i])return 0;
        if(way[0][i]<way[1][i])return 1;
    }
    return 0;
}
int bellman(int v,int aim)
{
    if(aim==v)return 0;
    while(!q.empty())q.pop();
    for(int i=0;i<=n;i++)
    {
        near[i]=i;
        inq[i]=0;
        d[i]=100000000;
    }
    d[v]=0;q.push(v);
    int now,next,t;
    while(!q.empty())
    {
        now=q.front();q.pop();
        inq[now]=0;
        for(next=1;next<=n;next++)
        {
            if(next==now||next==v)continue;//防止产生环
            if(dis[now][next]!=-1&&(d[next]>(t=d[now]+dis[now][next]+p[now])||(d[next]==t&&cmp(now,near[next],next))))
            {
                d[next]=t;
                near[next]=now;
                if(inq[next])continue;
                q.push(next);
                inq[next]=1;
            }
        }
    }
    return d[aim]-p[v];
}
int main()
{
    while(~scanf("%d",&n)&&n)
    {
        int i,j;
        for(i=1;i<=n;i++)
          for(j=1;j<=n;j++)
            scanf("%d",&dis[i][j]);
        for(i=1;i<=n;i++)
          scanf("%d",&p[i]);
        int v,u,t;
        while(~scanf("%d%d",&v,&u))
        {
            if(v==-1||u==-1)break;
            t=bellman(v,u);
            printf("From %d to %d :\n",v,u);
            printf("Path: %d",v);
            K[0]=0;
            if(u!=v)
            {
              path(u,0);
              for(int i=0;i<K[0];i++)
                printf("-->%d",way[0][i]);
            }
            printf("\nTotal cost : %d\n\n",t);
        }
    }
}


目录
相关文章
|
5月前
|
Java
hdu1016 Prime Ring Problem【素数环问题(经典dfs)】
hdu1016 Prime Ring Problem【素数环问题(经典dfs)】
23 0
|
人工智能
codeforces 1092——F:Tree with Maximum Cost (树上DP)
codeforces 1092——F:Tree with Maximum Cost (树上DP)
93 0
HDU-1016,Prime Ring Problem(DFS+素数)
HDU-1016,Prime Ring Problem(DFS+素数)
ZOJ Problem Set - 3758 素数
ZOJ Problem Set - 3758 素数
80 0