您的位置:首页 > 其它

poj3268 - Silver Cow Party (两次最短路)

2018-04-05 15:17 274 查看

题意:

给了三个整数n,m,x  n代表村庄数,m代表路径数,x代表终点。每个村庄有头奶牛,要到x去,再回来,求两次的最短路径的最大情况。

解法:

从x回来的过程的最短路容易求,运用dijkstra算法直接就能求。从起点到x的过程可以看成从x到起点的反过程,因为是单向路,那么通过把所有路的方向颠倒就能算这种情况的最短路,即maps[i][j]变成maps[j][i],可以直接通过颠倒i,j即可

AC代码:

#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdio>
using namespace std;
#define inf 1<<29;
int n,m,x;
int vis[1010];
int d[1010]; //从起点到x的最短路
int dback[1010]; //从x返回的最短路
int maps[1010][1010];
int dijkstra()
{
int ans;
for(int i=1;i<=n;i++)
{
vis[i]=0;
dback[i]=maps[i][x];
d[i]=maps[x][i];
}
int k,min;
for(int i=1;i<=n;i++)
{
min=inf;
for(int j=1;j<=n;j++)
{
if(!vis[j]&&d[j]<min)
{
min=d[j];
k=j;
}
}
vis[k]=1;
for(int j=1;j<=n;j++)
{
if(!vis[j]&&maps[k][j]+d[k]<d[j])
{
d[j]=maps[k][j]+d[k];
}
}
}
for(int i=1;i<=n;i++)
vis[i]=0;
for(int i=1;i<=n;i++)
{
min=inf;
for(int j=1;j<=n;j++)
{
if(!vis[j]&&dback[j]<min)
{
min=dback[j];
k=j;
}
}
vis[k]=1;
for(int j=1;j<=n;j++)
{
if(vis[j]==0&&maps[j][k]+dback[k]<dback[j])
{
dback[j]=maps[j][k]+dback[k];
}
}
}
ans=-1;
for(int i=1;i<=n;i++)
{
if(d[i]+dback[i]>ans)
ans=d[i]+dback[i];
}
return ans;
}
int main()
{
scanf("%d%d%d",&n,&m,&x);
int a,b,c;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(i!=j)
{
maps[i][j]=inf;
}
else
{
maps[i][j]=0;
}
}
}
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&a,&b,&c);
maps[a][b]=c;
}
int anss=dijkstra();
printf("%d\n",anss);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ACM