poj 3268 dijkstra

来源:互联网 发布:史丹利的寓言 for mac 编辑:程序博客网 时间:2024/05/19 03:44

题意:

    n个点,m条边,终点为x,问从某点到x,再回来,最大权值和为多少。

题解:

   正图一次从x点开始的dijkstra,再来个反图,从x点开始的dijkstra。把两个dist数组加和找最大。


#include<stdio.h>#define MX 111111111int 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;}