POJ 3268 Silver Cow Party(最短路 dijkstra求任意两点最短路)

题意:奶牛派对:有分别来自 N 个农场的 N 头牛去农场 X 嗨皮,农场间由 M 条有向路径连接。每头牛来回都挑最短的路走,求它们走的路的最大长度?奶牛派对:有分别来自 N 个农场的 N 头牛去农场 X 嗨皮,农场间由 M 条有向路径连接。每头牛来回都挑最短的路走,求它们走的路的最大长度?
开始思路,就是求某个点到x加上x到这某个点距离最大,直接floyed,1000数据果然TLE,dijkstra只能求一点到多点的最短路,这里开始多只奶牛到x的最短路,就不会了。。。太弱 看别人题解,发现dijkstra 修改一下 也可以求多点到一点最短路。
方法:最短路径只需要从x到i的最短路径代表他们返回的最短路径,然后将所有边反过来,再从i到x的最短路径代表他们来参加聚会的最短路径,这样对应相加找出一个最大值就可以了,当然其实不需要将所有边反过来,只需要将map的行和列对换一下就可以了。
floyed TLE

这里写代码片

两次dijkstra。

#include
#include
#include
using namespace std;
int M[1010][1010],d1[1010],d2[1010],visit[1010],n,m,x;

void dijkstra(int *d)
{
    memset(visit,0,sizeof(visit));
    visit[x]=1;
    for(int i=1;i<=n;i++)
     d[i]=M[x][i];
    for(int i=2;i<=n;i++)
    {
        int index,minn=99999999;
        for(int j=1;j<=n;j++)
        {
            if(!visit[j]&&d[j]index=j;
                minn=d[j];
            }
        }
        visit[index]=1;
        for(int j=1;j<=n;j++)
        {
            if(!visit[j]&&d[j]>d[index]+M[index][j])
                d[j]=d[index]+M[index][j];
        }
    }
}

int main()
{
   while(~scanf("%d %d %d",&n,&m,&x))
   {
       for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
        if(i==j) M[i][j]=0;
       else M[i][j]=99999999;
       for(int i=1;i<=m;i++)
       {
           int a,b,c;
           scanf("%d %d %d",&a,&b,&c);
           M[a][b]=c;
       }
       dijkstra(d1);
       for(int i=1;i<=n;i++)
        for(int j=1;j<=i;j++)
        swap(M[i][j],M[j][i]);
       dijkstra(d2);
       int maxx=-1;
       for(int i=1;i<=n;i++)
        maxx=max(maxx,d1[i]+d2[i]);
       printf("%d\n",maxx);
   }
}

你可能感兴趣的:(算法之最短路径)