您的位置:首页 > 其它

POJ 1734 Sightseeing trip 无向图的最小环

2013-05-21 23:41 323 查看
//============================================================================
// Name        : POJ1734.cpp
// Author      : wly
// Version     :
// Copyright   : 最小环问题
// Description : 无向图最小环,floyd,需要求出路径
//				 在floyd求最小环长度的基础上,增加一个p

数组用于存放最小环经过的路径
//				 若p[i][j] = k则说明路径为i->k->j,在每次更新最小环时更新路径,使用dfs递归获得路径
//============================================================================

#include <iostream>
#include <cstdlib>
#include <cstdio>
#define MAX_N 110
#define INF 1<<29
using namespace std;
int n, //点数
g[MAX_N][MAX_N],//原图
dis[MAX_N][MAX_N], //最短路径图
p[MAX_N][MAX_N],  //路径图
path[MAX_N], //最终最小环的路径
pathLength; //最小环的路径长度
//dfs获取i->j的路径
void dfs(int i, int j) {
int k = p[i][j];
if (k == 0) {
path[pathLength++] = j;
return;
}
dfs(i, k);
dfs(k, j);
}

int minCircuit() {
int ans = INF;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
dis[i][j] = g[i][j] == 0 ? INF : g[i][j];
//floyd计算最短路径
for (int k = 1; k <= n; k++) {
for (int i = 1; i <= k; i++)
for (int j = i + 1; j <= k; j++)
if (g[i][k] && g[k][j]) {//从k点出发,回到k点
//最小环,i点到j点的最短路径+i点到k点的长度+k点到j点的长度
int tmp = dis[i][j] + g[i][k] + g[k][j];
if (tmp < ans) {
ans = tmp;
pathLength = 0;
//更新最小环的路径,从i点开始,走i->j的最短路径,再最后加上k点即可
path[pathLength++] = i;
dfs(i, j);
path[pathLength++] = k;
}
}
//floyd最短路径
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++) {
int tmp = dis[i][k] + dis[k][j];
if (tmp < dis[i][j]) {
dis[i][j] = tmp;
p[i][j] = k;
}
}
}
return ans;
}

int main() {
int m;
while (~scanf("%d%d", &n, &m)) {
memset(p, 0, sizeof(p));
memset(g, 0, sizeof(g));
for (int i = 0; i < m; i++) {
int _fn, _sn, _dis;
scanf("%d%d%d", &_fn, &_sn, &_dis);
g[_fn][_sn] = g[_sn][_fn] = _dis;
}
int ans = minCircuit();
if (ans == INF)
printf("No solution.\n");
else
for (int i = 0; i < pathLength; i++)
printf("%d%c", path[i], (i == pathLength - 1) ? '\n' : ' ');
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: