POJ 3268 Silver Cow Party(最短路径dijkstra算法)

来源:互联网 发布:淘宝跳转链接 编辑:程序博客网 时间:2024/06/05 05:07

题目大意:

有限输入的数据N,M,X。N表示有N个农场,每个农场有一头奶牛;M表示连接这N个农场的M条边(有向边),X表示农场的一个编号(1,2,...,n)。

现在每个农场的牛都要走到编号为X的农场上去(选择最短路走),并返回自己的农场(选择最短路走),要求输出这些n头牛走的路程中(去+回的路程和)的最大值。

解题思路:

一个很简单的最短路径问题,用两次dijkstra算法就可以了,还要用到了矩阵的转置。首先用一次dijkstra算法(求编号为X的农场到其他农场的最短距离),求出每个农场的牛到X农场的最短距离。然后将矩阵(保存有向路径的信息)转置,在用一次dijkstra算法(求编号为X的农场到其他农场的最短距离),也就是求出了每头牛返回自己农场的最短距离。

如果不进行矩阵的转置,对于没有牛都用到一次dijkstra算法,那么时间复杂度就会增加,会出现超时。所以,在求每头牛返回的最短路径中,进行一次矩阵的转置,是把所有的有向边改变方向,只需一次dijkstra算法就可以了。

代码:

#include<cstdio>#include<cstring>#define Max 100000#define M 1005int time[M],a[M][M],dis[M],vis[M];int n,m,x;void dijkstra(int v){    int i,j,u;    for(int i=0;i<n;i++){        dis[i]=a[v][i];        vis[i]=0;    }    int min;    vis[v]=1;    for(i=1;i<n;i++){        min=Max;u=-1;        for(j=0;j<n;j++){            if(vis[j]==0 && dis[j]<min){                u=j;min=dis[j];            }        }        vis[u]=1;        for(j=0;j<n;j++){            if(vis[j]==0 && dis[j]>dis[u]+a[u][j]){                dis[j]=dis[u]+a[u][j];            }        }    }    return ;}int main(){    int f,t,c;    while(~scanf("%d%d%d",&n,&m,&x)){        for(int i=0;i<n;i++){            for(int j=0;j<n;j++){                if(i==j){                    a[i][j]=0;                    continue;                }                a[i][j]=Max;            }        }        for(int i=0;i<m;i++){            scanf("%d%d%d",&f,&t,&c);            a[f-1][t-1]=c;        }        //memset(vis,0,sizeof(vis));        memset(time,0,sizeof(time));        dijkstra(x-1);        for(int i=0;i<n;i++){   //去时的最短时间            time[i]=dis[i];        }        for(int i=0;i<n;i++){   //矩阵转置            for(int j=i+1;j<n;j++){                int tmp;                tmp=a[i][j];                a[i][j]=a[j][i];                a[j][i]=tmp;            }        }        dijkstra(x-1);        for(int i=0;i<n;i++){   //返回时的最短时间            time[i]+=dis[i];        }        int max=0;        for(int i=0;i<n;i++){            if(max<time[i])                max=time[i];        }        printf("%d\n",max);    }    return 0;}


0 0