POJ 1734 无向图最小环/有向图最小环

给定一张图,求图中一个至少包含三个点的环,环上的点不重复,并且环上的边的长度之和最小.

点数不超过100个

输出方案

无向图:

 1 /*Huyyt*/
 2 #include<bits/stdc++.h>
 3 #define mem(a,b) memset(a,b,sizeof(a))
 4 #define pb push_back
 5 using namespace std;
 6 typedef long long ll;
 7 typedef unsigned long long ull;
 8 const int mod = 1e9 + 7;
 9 const int gakki = 5 + 2 + 1 + 19880611 + 1e9;
10 const int MAXN = 3e2 + 5, MAXM = 2e5 + 5;
11 int a[MAXN][MAXN], d[MAXN][MAXN], pos[MAXN][MAXN];
12 int n, m;
13 int ans = 0x3f3f3f3f;
14 vector<int> path;
15 void get_path(int x, int y)
16 {
17         if (pos[x][y] == 0)
18         {
19                 return ;
20         }
21         get_path(x, pos[x][y]);
22         path.push_back(pos[x][y]);
23         get_path(pos[x][y], y);
24 }
25 int main()
26 {
27         scanf("%d %d", &n, &m);
28         mem(a, 0x3f);
29         for (int i = 1; i <= n; i++)
30         {
31                 a[i][i] = 0;
32         }
33         for (int i = 1; i <= m; i++)
34         {
35                 int x, y, z;
36                 scanf("%d %d %d", &x, &y, &z);
37                 a[x][y] = a[y][x] = min(a[x][y], z);
38         }
39         memcpy(d, a, sizeof(a));
40         for (int k = 1; k <= n; k++)
41         {
42                 //刚开始循环时 d[i][j]表示经过编号不超过k-1的节点从i到j的最短路
43                 for (int i = 1; i < k; i++)
44                 {
45                         for (int j = i + 1; j < k; j++)
46                         {
47                                 if ((ll)d[i][j] + a[j][k] + a[k][i] < ans)
48                                 {
49                                         ans = d[i][j] + a[j][k] + a[k][i];
50                                         path.clear();
51                                         path.push_back(i);
52                                         get_path(i, j);
53                                         path.push_back(j), path.push_back(k);
54                                 }
55                         }
56                 }
57                 for (int i = 1; i <= n; i++)
58                 {
59                         for (int j = 1; j <= n; j++)
60                         {
61                                 if (d[i][j] > d[i][k] + d[k][j])
62                                 {
63                                         d[i][j] = d[i][k] + d[k][j];
64                                         pos[i][j] = k;
65                                 }
66                         }
67                 }
68         }
69         if (ans == 0x3f3f3f3f)
70         {
71                 printf("No solution.\n");
72         }
73         else
74         {
75                 for (int i = 0; i < path.size(); i++)
76                 {
77                         printf("%d ", path[i]);
78                 }
79                 printf("\n");
80         }
81         return 0;
82 }
//无向图最小环

有向图:

有向图直接floyd求出最小的自身到自身的距离 即为答案(注意初始化全为INF)

转载于:https://www.cnblogs.com/Aragaki/p/9568810.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值