POJ 1734

题意:给定一个无向图,有重边,求最小代价环,环上点数必须大于2

题解:类似floyd,在进行最小距离的同时,枚举点k的两端是否形成回路,如果形成,必定是没有经过重复点的,因为那样就不是最小距离,而经过点k的弧的松弛操作还没进行,所以也不会经过k

View Code
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 const int inf=1<<29;
 6 int dist[105][105],map[105][105],pre[105][105];
 7 int main()
 8 {
 9     int n,m;
10     while(scanf("%d%d",&n,&m)!=EOF)
11     {
12         memset(map,-1,sizeof(map));
13         memset(pre,-1,sizeof(pre));
14         memset(dist,-1,sizeof(dist));
15         for(int i=0; i<m; i++)
16         {
17             int a,b,c;
18             scanf("%d%d%d",&a,&b,&c);
19             if(dist[a][b]==-1)
20                 dist[a][b]=dist[b][a]=map[a][b]=map[b][a]=c;
21             else
22                 dist[a][b]=dist[b][a]=map[a][b]=map[b][a]=min(map[a][b],c);
23             pre[a][b]=a;
24             pre[b][a]=b;
25         }
26         for(int i=1;i<=n;i++)
27             dist[i][i]=map[i][i]=0;
28         int ans=inf,path[105],top;
29         for(int k=1; k<=n; k++)
30         {
31             for(int i=1; i<k; i++)
32                 for(int j=i+1; j<k; j++)
33                 {
34                     if(dist[i][j]!=-1&&map[i][k]!=-1&&map[k][j]!=-1&&ans>dist[i][j]+map[i][k]+map[k][j])
35                     {
36                         ans=dist[i][j]+map[i][k]+map[k][j];
37                         int t=j;
38                         top=0;
39                         while(t!=i)
40                         {
41                             path[top++]=t;
42                             t=pre[i][t];
43                         }
44                         path[top++]=i;
45                         path[top++]=k;
46                     }
47                 }
48             for(int i=1; i<=n; i++)
49                 for(int j=1; j<=n; j++)
50                     if(dist[i][k]!=-1&&dist[k][j]!=-1&&(dist[i][j]==-1||dist[i][j]>dist[i][k]+dist[k][j]))
51                     {
52                         dist[i][j]=dist[i][k]+dist[k][j];
53                         pre[i][j]=pre[k][j];
54                     }
55         }
56         if(ans==inf)
57         {
58             printf("No solution.\n");
59             continue;
60         }
61         for(int i=0; i<top-1; i++)
62             printf("%d ",path[i]);
63         printf("%d\n",path[top-1]);
64     }
65     return 0;
66 }

转载于:https://www.cnblogs.com/tmeteorj/archive/2012/09/20/2695540.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值