题意:
n个点,m条边,终点为x,问从某点到x,再回来,最大权值和为多少。
题解:
正图一次从x点开始的dijkstra,再来个反图,从x点开始的dijkstra。把两个dist数组加和找最大。
#include<stdio.h>
#define MX 111111111
int map[1010][1010],mapcopy[1010][1010],dist1[1010],dist2[1010],s[1010],n,m,x;
void dijkstra(int v0)
{
for(int i=1;i<=n;i++)
{
dist1[i]=map[v0][i];
s[i]=0;
}
s[v0]=1;
dist1[v0]=0;
for(int i=1;i<=n;i++)
{
int min=MX,u;
for(int j=1;j<=n;j++)
{
if(!s[j]&&dist1[j]<min)
{
min=dist1[j];
u=j;
}
}
s[u]=1;
for(int j=1;j<=n;j++)
if(!s[j]&&dist1[u]+map[u][j]<dist1[j])
dist1[j]=dist1[u]+map[u][j];
}
}
void dijkstra1(int v0)
{
for(int i=1;i<=n;i++)
{
dist2[i]=mapcopy[v0][i];
s[i]=0;
}
s[v0]=1;
dist2[v0]=0;
for(int i=1;i<=n;i++)
{
int min=MX,u;
for(int j=1;j<=n;j++)
{//printf("!j=%d dist2=%d\n",j,dist2[j]);
if(!s[j]&&dist2[j]<min)
{
min=dist2[j];
u=j;
}
}
s[u]=1;
// printf("!u=%d\n",u);
for(int j=1;j<=n;j++)
if(!s[j]&&dist2[u]+mapcopy[u][j]<dist2[j])
dist2[j]=dist2[u]+mapcopy[u][j];
}
}
int main()
{
while(scanf("%d%d%d",&n,&m,&x)!=EOF)
{
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
map[i][j]=mapcopy[i][j]=MX;
for(int i=0;i<m;i++)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
map[a][b]=mapcopy[b][a]=c;
}
dijkstra(x);
dijkstra1(x);
int max=0;
for(int i=1;i<=n;i++)
if(dist1[i]+dist2[i]>max)
max=dist1[i]+dist2[i];
// printf("dist1=%d dist2=%d\n",dist1[i],dist2[i]);
printf("%d\n",max);
}
return 0;
}