poj 1734 无向图的最小环
无向图的最小环:从某个点出发走回自己的最短路径,路径上至少有三个点
搜索做法:
View Code
1 //PKU 1734 无向图的最小环,搜索做法
2 #include<stdio.h>
3 #include<vector>
4 #include<string.h>
5 using namespace std;
6 const int N = 110;
7 const int inf = 1e8;
8 struct node{
9 int to,w;
10 };
11 vector<node> QQ[N];
12 bool vis[N];
13 int S,ans[N],temp[N],best,ans_nodes;
14 void dfs(int now,int fa,int dep,int sum)
15 {
16 int i;
17 if(now==S&&vis[S])
18 {
19 if(sum<best)
20 {
21 best=sum;ans_nodes=dep;
22 for(i=0;i<dep;i++)
23 ans[i]=temp[i];
24 }
25 return ;
26 }
27 temp[dep]=now;
28 for(i=0;i<QQ[now].size();i++)
29 {
30 if(QQ[now][i].to!=S&&vis[QQ[now][i].to]) continue;
31 if(QQ[now][i].to==fa) continue;
32 vis[QQ[now][i].to]=true;
33 if(QQ[now][i].w+sum<best)
34 dfs(QQ[now][i].to,now,dep+1,sum+QQ[now][i].w);
35 vis[QQ[now][i].to]=false;
36 }
37 }
38 int main()
39 {
40 int n,m;
41 int i,w,s,t;
42 scanf("%d%d",&n,&m);
43 node tmp;
44 for(i=0;i<m;i++)
45 {
46 scanf("%d%d%d",&s,&t,&w);
47 tmp.to=t;
48 tmp.w=w;
49 QQ[s].push_back(tmp);
50 tmp.to=s;
51 QQ[t].push_back(tmp);
52 }
53 best=inf;//错误原因:全局变量在这里又定义了一遍,汗!!!!
54 for(i=1;i<=n;i++)
55 {
56 memset(vis,false,sizeof(vis));
57 S=i;
58 dfs(i,-1,0,0);
59 }
60 if(best==inf) printf("No solution.\n");
61 else
62 {
63 printf("%d",ans[0]);
64 for(i=1;i<ans_nodes;i++)
65 printf(" %d",ans[i]);
66 }
67 printf("\n");
68 return 0;
69 }
floyd 做法,每次假设k是环中最大的点
#include <cstdio> #include <cstring> const int INF = 1000000; int map[110][110]; int dis[110][110]; int pre[110][110]; int n; bool update(int &x, int y) { if(y < x) { x = y; return true; } return false; } int tot; int ans[110]; int ret; // pre[i][j]表示i到j最短路径上的第一个点 void solve() { ret = INF; for(int k = 0; k < n; k++) { for(int i = 0; i < k; i++) { for(int j = i + 1; j < k; j++) { if(update(ret, map[i][k] + dis[i][j] + map[k][j])) { tot = 0; ans[tot++] = k; int p = i; while(p != -1) { ans[tot++] = p; p = pre[p][j]; } } } } for(int i = 0; i < n; i++) { for(int j = 0; j < n; j++) { if(dis[i][k] + dis[k][j] < dis[i][j]) { pre[i][j] = pre[i][k]; dis[i][j] = dis[i][k] + dis[k][j]; } } } } } void print() { if(ret == INF) { printf("No solution.\n"); } else { // printf("ret=%d\n",ret); for(int i = 0; i < tot; i++) { if(i) printf(" "); printf("%d", ans[i] + 1); } puts(""); } } int main() { int t, m, a, b, c; while(scanf("%d", &n) != EOF) { if(n == -1) break; scanf("%d", &m); memset(pre, -1, sizeof(pre)); for(int i = 0; i < n; i++) { map[i][i] = dis[i][i] = 0; for(int j = 0; j < n; j++) if(i != j) { dis[i][j] = map[i][j] = INF; } } for(int i = 0; i < m; i++) { scanf("%d%d%d", &a, &b, &c); a--; b--; if(c < map[a][b]) { dis[b][a] = map[b][a] = c; dis[a][b] = map[a][b] = c; pre[a][b] = b; pre[b][a] = a; } } solve(); print(); } return 0; }