POJ 3268 Silver Cow Party(找最短路径的最大值+两次Dijkstra算法)

来源:互联网 发布:邯郸煤炭软件 编辑:程序博客网 时间:2024/06/03 22:57

      这道题是今下午练习赛的题目,感觉题目很好。

      题意大致是,每头牛要从起点去终点,再从终点回到起点,并且从起点到终点和从终点到起点为单向路径,求所有牛里面 起点到终点+终点到起点 的最短路径里面最大值为多少。

      大致思路为:用两次dikstra算法分别求起点到终点和终点到起点的最短距离,因为是单向的所以可以通过转置进行转换,否则还要另开一个数组一个一个模拟所有点到目标,通过转置就可以把路径的方向更改。

      AC代码(63ms,还是很快的):

 #include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int N = 1100;
int a[N][N], dis[N], sum[N], visit[N];
int n, m, x;
const int inf = 1100000;
int main()
{
    while(scanf("%d %d %d", &n, &m, &x)!=EOF)
    {
        memset(sum,0,sizeof(sum));
        memset(a,127,sizeof(a));
        for(int i=0;i<m;i++)
        {
            int c, b, w;
            scanf("%d %d %d", &c, &b, &w);
            a[c][b]=w;
        }
        for(int i=1;i<=n;i++)
        {
            dis[i]=a[x][i];
        }
        memset(visit,0,sizeof(visit));
        visit[x]=1;
        for(int i=1;i<n;i++)//Dijkstra算法求终点到各个点的最短路径
        {
            int u, Min=inf;
            for(int j=1;j<=n;j++)
            {
                if(visit[j]==0&&dis[j]<Min)
                {
                    u=j;
                    Min=dis[j];
                }
            }
            if(Min==inf) break;
            visit[u]=1;
            for(int j=1;j<=n;j++)
            {
                if(visit[j]==0&&dis[u]+a[u][j]<dis[j])
                {
                    dis[j]=dis[u]+a[u][j];//dis[j]表示终点到j点的最短距离
                }
            }
        }
        for(int i=1;i<=n;i++)
        {
            if(dis[i]!=inf)
            {
                sum[i]+=dis[i];
            }
        }
        for(int i=1;i<=n;i++)
        {
            for(int j=i;j<=n;j++)
            {
                int tmp;
                tmp=a[i][j],a[i][j]=a[j][i],a[j][i]=tmp;//交换单向路径的方向
            }
        }
        for(int i=1;i<=n;i++)
        {
            dis[i]=a[x][i];
        }
        memset(visit,0,sizeof(visit));
        visit[x]=1;
        for(int i=1;i<n;i++)//Dijkstra算法求起点到各个点的最短路径
        {
            int u, Min=inf;
            for(int j=1;j<=n;j++)
            {
                if(visit[j]==0&&dis[j]<Min)
                {
                    u=j;
                    Min=dis[j];
                }
            }
            if(Min==inf)  break;
            visit[u]=1;
            for(int j=1;j<=n;j++)
            {
                if(visit[j]==0&&dis[u]+a[u][j]<dis[j])
                {
                    dis[j]=dis[u]+a[u][j];//dis[j]表示起点到j点的最短距离
                }
            }
        }
        for(int i=1;i<=n;i++)
        {
            if(dis[i]!=inf)
            {
                sum[i]+=dis[i];
            }
        }
        int Max=-1;
        for(int i=1;i<=n;i++)
        {
            Max=max(Max,sum[i]);
        }
        printf("%d\n",Max);
    }
    return 0;
}


  

原创粉丝点击