zoukankan      html  css  js  c++  java
  • Minimum Transport Cost HDU1385(路径打印)

    最短路的路径打印问题 同时路径要是最小字典序

    字典序用floyd方便很多

    学会了两种打印路径的方法!!!

    #include <stdio.h>
    #include <string.h>
    #define N 110
    #define INF 1000000000
    int d[N][N],path[N][N],c[N];
    int n,cost;
    int s,t;
    
    void input()
    {
        int i,j,w;
        for(i=1; i<=n; i++)
            for(j=1; j<=n; j++)
            {
                scanf("%d",&d[i][j]);
                if(d[i][j]==-1) d[i][j]=INF;
                path[i][j]=j;
            }
        for(i=1; i<=n; i++) 
            scanf("%d",&c[i]);
    
        return ;
    }
    
    void Floy()
    {
        int i,j,k;
    
        for(k=1; k<=n; k++)  //中转站k
            for(i=1; i<=n; i++) //起点和终点i,j
                for(j=1; j<=n; j++)
                {
                    if( d[i][j] > d[i][k]+d[k][j]+c[k] )
                    {
                        d[i][j]=d[i][k]+d[k][j]+c[k];
                        path[i][j]=path[i][k];
                    }
                    
                    else if( d[i][j] == d[i][k]+d[k][j]+c[k] )
                    {
                        if(   path[i][j] > path[i][k])
                        {
                            d[i][j]=d[i][k]+d[k][j]+c[k];
                            path[i][j]=path[i][k];
                        }
                    }
                    
                }
        return ;
    }
    
    void print_path(int u , int v) //u是起点v是终点
    {
        int k;
        if(u==v)
        {
            printf("%d",v);
            return ;
        }
        k=path[u][v];
        printf("%d-->",u);
        print_path(k,v);
    }
    int main()
    {
        while(scanf("%d",&n)!=EOF && n)
        {
            input();
            Floy();
            
            while(scanf("%d%d",&s,&t))
            {
                if( s==-1 && t==-1) break;
                cost=d[s][t];
                if(s==t)  //起点和终点相同
                {
                    printf("From %d to %d :
    ",s,t);
                    printf("Path: %d
    ",s);
                    printf("Total cost : %d
    
    ",cost);
                    continue;
                }
                printf("From %d to %d :
    ",s,t);
                printf("Path: ");
                print_path(s,t);
                printf("
    ");
                printf("Total cost : %d
    
    ",cost);
            }
        }
        return 0;
    }
    View Code

    dijkstra实现

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int maxn=51;
    const int inf=100000000;
    int pos=0;
    int G[maxn][maxn],d[maxn],c[maxn],pre[maxn];
    bool vis[maxn];
    int n,st,ed;
    void dfs(int u,char *s)
    {
        if(u==st)  return ;
        dfs(pre[u],s);
        s[pos++]=u+'0';
    }
    bool cmp(int u,int v)
    {
        char s1[maxn],s2[maxn];
        pos=0;
        dfs(u,s1);
        s1[pos]='';
        pos=0;
        dfs(v,s2);
        s2[pos]='';
        if(strcmp(s1,s2)==1) return true;
        return false;
    }
    void dijkstra(int st)
    {
        fill(d,d+maxn,inf);
        for(int i=1;i<=n;i++)  pre[i]=i;
        d[st]=0;
        for(int i=1;i<=n;i++)
        {
            int u=-1,MIN=inf;
            for(int j=1;j<=n;j++)
            {
                if(!vis[j]&&d[j]<MIN)
                {
                    MIN=d[j];
                    u=j;
                }
            }
            if(u==-1)  return ;
            vis[u]=true;
            for(int v=1;v<=n;v++)
            {
                if(G[u][v]!=inf&&vis[v]==false&&G[u][v]+d[u]+c[u]<d[v])
                {
                    d[v]=G[u][v]+d[u]+c[u];
                    pre[v]=u;
                }
                else
                {
                    if(G[u][v]+d[u]+c[u]==d[v]&&cmp(v,u))
                        pre[v]=u;
                }
            }
    
        }
    }
    
    void show(int v)
    {
        if(v==st)
        {
            cout<<v;
            return ;
        }
        show(pre[v]);
        cout<<"-->"<<v;
    }
    int main()
    {
        while (cin>>n&&n!=0)
    
        {
        memset(vis,false,sizeof(vis));
        //fill(G[0],G[0]+maxn*maxn,inf);
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                cin>>G[i][j];
                if(G[i][j]==-1)
                    G[i][j]=inf;
            }
        }
        for(int i=1;i<=n;i++)
            cin>>c[i];
        while (cin>>st>>ed)
        {
            memset(vis,false,sizeof(vis));
            if(st==-1&&ed==-1)  break;
            if(st==ed)
    
                {
                    printf("From %d to %d :
    ",st,ed);
                    printf("Path: %d
    ",st);
                    printf("Total cost : 0
    
    ");
    
                }
            else{
            dijkstra(st);
            printf("From %d to %d :
    ",st,ed);
            printf("Path: ");
            show(ed);
            cout<<endl;
            printf("Total cost : %d
    ",d[ed]-c[st]);
            cout<<endl;
            }
        }
        }
    }
    View Code
  • 相关阅读:
    jstree 实现异步加载子节点
    创建 widget 窗口小组件
    Android(permission)常用权限
    Android 之 补间动画
    补间动画之 AlphaAnimation
    (转)向对象开发与面向组件开发的区别
    Android Drawable文件夹对应像素密度
    Notification(通知) 简单用法
    AlarmManager 用法
    关于IntentService 用法
  • 原文地址:https://www.cnblogs.com/bxd123/p/10333116.html
Copyright © 2011-2022 走看看