無向グラフソルバー又は図側に最小量の三点を含むリング用。
観光旅行
質問の意味:なし最小フープマップを解きます
ソリューション:私が使用することを選んだので、それは、無向グラフですので\(フロイドを\) 、その後、使用\(フロイドは\)である(DP \)\特性、あなたは簡単に解決することができます。
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
using namespace std;
#define ll long long
#define maxn 110
int n, m, ans;
ll a[maxn][maxn], dis[maxn][maxn];
int pos[maxn][maxn];
vector <int> path;
void getpath(int x, int y)
{
if(pos[x][y] == 0) return;
getpath(x, pos[x][y]);
path.push_back(pos[x][y]);
getpath(pos[x][y], y);
}
int main()
{
ans = 1e9;
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++) a[i][j] = 1e9, a[i][j] *= 1e9, dis[i][j] = 1e9, dis[i][j] *= 1e9;
for(int i = 1; i <= m; i++)
{
int u, v; long long w;
scanf("%d%d%lld", &u, &v, &w);
dis[u][v] = dis[v][u] = min(dis[u][v], w);
a[u][v] = a[v][u] = dis[u][v];
}
for(int k = 1; k <= n; k++)
{
for(int i = 1; i < k; i++)
for(int j = i + 1; j < k; j++)
{
if(dis[i][j] + a[i][k] + a[k][j] < ans)
{
ans = dis[i][j] + a[i][k] + a[k][j];
path.clear();
path.push_back(i);
getpath(i, j);
path.push_back(j);
path.push_back(k);
}
}
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
if(dis[i][j] > dis[i][k] + dis[k][j])
{
dis[i][j] = dis[i][k] + dis[k][j]; pos[i][j] = k;
}
}
if(ans == 1e9)
{
printf("No solution.\n");
return 0;
}
for(int i = 0; i < path.size(); i++) printf("%d ", path[i]);
return 0;
}
図のために、ヒープ最適化から始まるの直接列挙\(ダイクストラ\)から最短の単一のソースを解決する、\(S \)点は、最短経路を更新する\(S \)正の無限大への点から、ときに第二の訪問\(S \)の場合、\(D [S]は\)によるものである\(S \)最小のループ長。