luoguP6175 无向图的最小环问题
无向图的最小环问题
题目描述
给定一张无向图,求图中一个至少包含 3 3 3 个点的环,环上的节点不重复,并且环上的边的长度之和最小。该问题称为无向图的最小环问题。在本题中,你需要输出最小的环的边权和。若无解,输出 No solution.
。
输入格式
第一行两个正整数 n , m n,m n,m 表示点数和边数。
接下来 m m m 行,每行三个正整数 u , v , d u,v,d u,v,d,表示节点 u , v u,v u,v 之间有一条长度为 d d d 的边。
输出格式
输出边权和最小的环的边权和。若无解,输出 No solution.
。
样例 #1
样例输入 #1
5 7
1 4 1
1 3 300
3 1 10
1 2 16
2 3 100
2 5 15
5 3 20
样例输出 #1
61
提示
样例解释:一种可行的方案: 1 − 3 − 5 − 2 − 1 1-3-5-2-1 1−3−5−2−1。
对于 20 % 20\% 20% 的数据, n , m ≤ 10 n,m \leq 10 n,m≤10。
对于 60 % 60\% 60% 的数据, m ≤ 100 m\leq 100 m≤100。
对于 100 % 100\% 100% 的数据, 1 ≤ n ≤ 100 1\le n\leq 100 1≤n≤100, 1 ≤ m ≤ 5 × 1 0 3 1\le m\leq 5\times 10^3 1≤m≤5×103, 1 ≤ d ≤ 1 0 5 1 \leq d \leq 10^5 1≤d≤105。
无解输出包括句号。
#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
int n,m,e[105][105],ans =INT_MAX,d[105][105];
void Floyd()
{for (int k = 1;k <= n;k++){for (int i = 1;i <k;i++)for (int j = i+1;j <k;j++)if (i != j && j != k && k != i &&e[i][j]!=INF&& d[i][k] != INF && d[k][j] != INF){//printf("%d %d %d %d %d\n",k,i,j,e[i][j],e[i][j]+d[i][k]+d[k][j]);ans = min(ans,e[i][j]+d[i][k]+d[k][j]);}for (int i = 1;i <= n;i++)for (int j = 1;j <= n;j++)if (i != j && j != k && k != i && e[i][k] != INF && e[k][j] != INF){e[i][j] = min(e[i][j],e[i][k]+e[k][j]);e[j][i] = e[i][j];}}
}
int main(){scanf("%d%d",&n,&m);for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){if(i!=j){d[i][j]=e[i][j]=INF;}}}for (int i = 1;i <= m;i++){int x,y,z;scanf("%d%d%d",&x,&y,&z);e[x][y] = min(e[x][y],z);e[y][x] = e[x][y];d[x][y] = e[x][y];d[y][x] = e[x][y];}Floyd();if (ans == INT_MAX) puts("No solution.");else cout << ans << endl;return 0;
}