poj3268 单源最短路径+矩阵转置

来源:互联网 发布:php 支付码 编辑:程序博客网 时间:2024/06/07 18:03

这个题的意思是一群牛要聚会,在某一头牛的家里聚会,问所有的牛去这头牛的家来回的路径最短多少,因为是有向图,所以来回路径不一定一样长

思路就是先用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 999999using 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就转置两次了  */


0 0
原创粉丝点击