这个题的意思是一群牛要聚会,在某一头牛的家里聚会,问所有的牛去这头牛的家来回的路径最短多少,因为是有向图,所以来回路径不一定一样长
思路就是先用dijkstra求一遍去这头牛家的,然后将矩阵转置后,再dijkstra一下,那么回去的最短路也求出来了,最后两个最短路结果相加就是答案了。
在这里,要注意矩阵转置的时候,需要将矩阵对角线左下角和右上角对换,所以就是
void zhuanzhi()
{
for(int i = 1 ; i <= n ; i++)
for(int j = 1 ; j < i ; j++)
{
int t = tu[i][j];
tu[i][j] = tu[j][i];
tu[j][i] = t;
}
}
这里第二个for循环容易出错,因为如果j从1到n的话相当于转置两次,也就是又转回来啦-_-#
嗯,然后就是套模板咯。上代码。。。
注:输入第一行为点数n、边数m和源点x
第二行之后输入m行边
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <vector>
#include <cmath>
#include <queue>
#include <cstdlib>
#include <algorithm>
#define INF 999999
using namespace std;
int tu[1005][1005],dian[1005],fdian[1005],tf[1005],m,n,x,u,v,cost;
void init()
{
for(int i = 0 ; i < 1005 ; i++)
for(int j = 0 ; j < 1005 ; j++)
{
tu[i][j] = INF;
}
}
int dijkstra(int x)
{
int ans = 0,ji = 0,t,_min;
for(int i = 1 ; i <= n ; i++)
dian[i] = tu[x][i];
memset(tf,0,sizeof(tf));
dian[x] = 0;
tf[x] = 1;
for(int i = 1 ; i <= n-1 ; i++)
{
_min = INF;
for(int j = 1 ; j <= n ; j++)
{
if(tf[j] == 0 && dian[j] < _min)
{
_min = dian[j];
t = j;
}
}
ans += _min;
tf[t] = 1;
for(int j = 1 ; j <= n ; j++)
{
if( tf[j] == 0 && dian[j] > tu[t][j] + dian[t] )
{
dian[j] = dian[t] + tu[t][j];
}
}
}
return ans;
}
void zhuanzhi()
{
for(int i = 1 ; i <= n ; i++)
for(int j = 1 ; j < i ; j++)
{
int t = tu[i][j];
tu[i][j] = tu[j][i];
tu[j][i] = t;
}
}
int main(int argc, char *argv[])
{
while(scanf("%d%d%d",&n,&m,&x)!=EOF)
{
init();
for(int i = 1 ; i <= m ; i++)
{
scanf("%d%d%d",&u,&v,&cost);
tu[u][v] = cost;
}
dijkstra(x);
for(int i = 1; i <= n ; i++)
fdian[i] = dian[i];
zhuanzhi();
dijkstra(x);
int answer = -1;
for(int i = 1 ; i <= n ; i++)
{
if( dian[i] + fdian[i] > answer )
answer = dian[i] + fdian[i];
}
printf("%d\n",answer);
}
return 0;
}
/*
母牛聚会,输入点数边数和第几个牛是源点
有向图,所以来回可能路程不一样,所以来一趟dijkstra
再将矩阵转置再来一趟dijkstra,得到结果,不要忘了在dijkstra里面将
tf数组初始化,否则不行
而且,矩阵转置是 i: 1 -> n,j : 1 -> i,如果从1到n就转置两次了
*/