HDU1385 Minimum Transport Cost(最短路输出字典序路径floyd/逆序spfa)

题意:先给你一张你n * n的图,代表城市间的距离,然后,给出n个tax的费用,然后很多询问,问你a到b的最少费用,并且打印路径(字典序)

注意tax的费用起点和终点不算

floyd求字典序路径:

/* ***********************************************
Author        :devil
Created Time  :2016/6/2 11:35:15
************************************************ */
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <cmath>
#include <stdlib.h>
using namespace std;
const int N=105;
int n,mp[N][N],tax[N],path[N][N];
void floyd()
{
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            path[i][j]=j;
    for(int k=1;k<=n;k++)
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
            {
                int tmp=mp[i][k]+mp[k][j]+tax[k];
                if(tmp<mp[i][j])
                {
                    mp[i][j]=tmp;
                    path[i][j]=path[i][k];
                }
                else if(tmp==mp[i][j])
                    path[i][j]=min(path[i][j],path[i][k]);
            }
}
int main()
{
    //freopen("in.txt","r",stdin);
    int st,ed;
    while(~scanf("%d",&n)&&n)
    {
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
            {
                scanf("%d",&mp[i][j]);
                if(mp[i][j]==-1) mp[i][j]=0x3f3f3f3f;
            }
        for(int i=1;i<=n;i++)
            scanf("%d",&tax[i]);
        floyd();
        while(scanf("%d%d",&st,&ed)==2&&(st+ed)!=-2)
        {
            printf("""From %d to %d :\n",st,ed);
            printf("Path: %d",st);
            int tmp=st;
            while(tmp!=ed)
            {
                printf("-->%d",path[tmp][ed]);
                tmp=path[tmp][ed];
            }
            printf("\nTotal cost : %d\n\n",mp[st][ed]);
        }
    }
    return 0;
}

 

逆序spfa:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <queue>
#include <cmath>
#include <vector>
#include <algorithm>
using namespace std;
#define maxn 1005
#define inf 1e8
int a[maxn][maxn],tax[maxn],dis[maxn],fa[maxn],ans[maxn],n,x,y,temp;
bool vis[maxn];
void spfa()
{
    memset(vis,false,sizeof(vis));
    for(int i=1;i<=n;i++)
    {
        dis[i]=fa[i]=inf;
        vis[i]=false;
    }
    dis[y]=0;
    queue<int>q;
    q.push(y);
    vis[y]=true;
    while(!q.empty())
    {
        temp=q.front();
        q.pop();
        for(int i=1;i<=n;i++)
        {
            if(-1==a[i][temp]||i==temp) continue;
            else
            {
                if(dis[temp]+tax[i]+a[i][temp]<dis[i])
                {
                    dis[i]=dis[temp]+tax[i]+a[i][temp];
                    fa[i]=temp;
                    if(vis[i]==false)
                    {
                        q.push(i);
                        vis[i]=true;
                    }
                }
                else if(dis[temp]+tax[i]+a[i][temp]==dis[i]&&temp<fa[i]) fa[i]=temp;
            }
        }
        vis[temp]=false;
    }
    ans[0]=x;
    temp=0;
    while(fa[ans[temp]]!=inf)
    {
        ans[temp+1]=fa[ans[temp]];
        temp++;
    }
    printf("From %d to %d :\nPath: ",x,y);
    for(int i=0;i<temp;i++)
        printf("%d-->",ans[i]);
    printf("%d\n",ans[temp]);
    printf("Total cost : %d\n\n",dis[x]-tax[x]);
}
int main()
{
    while(~scanf("%d",&n)&&n)
    {
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                scanf("%d",&a[i][j]);
        for(int i=1;i<=n;i++)
            scanf("%d",&tax[i]);
        while(~scanf("%d%d",&x,&y)&&x!=-1)
        {
            if(x!=y) spfa();
            else
            {
                printf("From %d to %d :\n",x,y);
                printf("Path: %d\n",x);
                printf("Total cost : 0\n\n");
            }
        }
    }
    return 0;
}

 

posted on 2015-08-26 10:28  恶devil魔  阅读(205)  评论(0编辑  收藏  举报

导航