题目描述
- 旅游区可以表示为一张由(n)个节点 (m)条边组成无向图。我故地重游,却发现自己只想尽快地结束这次旅游。
- 我从景区的出发点(即(1)号节点)出发,却只想找出最短的一条回路重新回到出发点,并且中途不重复经过任意一条边。即:我想找出从出发点到出发点的小环。
输入格式
- 每个测试点有多组测试数据。
- 第一行有一个正整数表示数据组数。
- 接下来对于每组数据,第一行有两个正整数 ) 分别代表图的点数和边数。
- 接下来有行,每行三个整数表示之间存在一条长度为 的路径。
- 保证不存在重边,自环。
输出格式
- 对于每组测试数据,输出题目中所求的最小环的长度。
- 无解输出(-1) 。
样例
样例输入
2
3 3
1 2 1
2 3 1
3 1 1
4 5
1 2 2
2 3 2
3 4 2
1 4 2
1 3 5
样例输出
3
8
code
/*
2
3 3
1 2 1
2 3 1
3 1 1
4 5
1 2 2
2 3 2
3 4 2
1 4 2
1 3 5
*/
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e4 + 5, maxm = 4e4 + 5;
const int Inf = 0x3f3f3f3f;
struct node {
int to, next, val;
} e[maxm << 1];
int head[maxn], len;
int vis[maxn], dis[maxn];
void add(int a, int b, int c) {
e[len] = (node){ b, head[a], c };
head[a] = len++;
}
void Spfa(int x) {
memset(dis, 0x3f, sizeof(dis));
memset(vis, 0, sizeof(vis));
queue<int> q;
q.push(x);
dis[x] = 0;
while (!q.empty()) {
int u = q.front();
q.pop();
vis[u] = 0;
for (int i = head[u]; ~i; i = e[i].next) {
int v = e[i].to;
if (dis[v] > dis[u] + e[i].val) {
dis[v] = dis[u] + e[i].val;
if (!vis[v])
q.push(v), vis[v] = 1;
}
}
}
}
int main() {
int T;
scanf("%d", &T);
while (T--) {
int n, m;
cin >> n >> m;
memset(head, -1, sizeof(head));
len = 0;
for (int i = 1; i <= m; i++) {
int u, v, val;
cin >> u >> v >> val;
add(u, v, val);
add(v, u, val);
}
int ans = Inf;
for (int i = head[1]; ~i; i = e[i].next) {
int temp = e[i].val;
e[i].val = e[i ^ 1].val = Inf;
Spfa(1);
ans = std::min(ans, dis[e[i].to] + temp);
e[i].val = e[i ^ 1].val = temp;
}
if (ans == Inf)
ans = -1;
cout << ans << endl;
}
}