解析:
本题的意思是,求一个环的最小的那条边。
并且输出其这个环的点。
我们可以利用并查集,进行确定其是否有环路。在将所用的边从大到小排序。
利用 vector容器,pop_back() 和 push的特性。
起点为 u终点为 v寻找路径。
代码:
#include<bits/stdc++.h>
using namespace std;
#define PII pair<int,int>
const int N = 2e5 + 10;
struct edge {int u, v, w;} e[N]; //存输入的所有边
vector<PII> graph[N]; //邻接表存图,first存通往的点, second存边权
int n, m, U, V, W, fa[N], vis[N];
vector<int> path; //存遍历顺序
bool cmp(edge a, edge b)
{return a.w > b.w;
}
int find(int x)
{ return fa[x] == x ? x : fa[x] = find(fa[x]);
} //并查集查询
void merge(int x, int y)
{fa[find(x)] = find(y);
} //并查集合并
bool dfs(int now){if(now == V){return true; //找到答案,直接回溯}for(auto it: graph[now]){if(it.second < W || vis[it.first]) continue;vis[it.first] = true; //标记此点已走过path.push_back(it.first);if(dfs(it.first)) return true;path.pop_back();}return false;
}
void solve(){cin >> n >> m;for(int i = 1; i <= n; i ++) fa[i] = i, graph[i].clear(), vis[i] = false; //初始化for(int i = 1; i <= m; i ++) cin >> e[i].u >> e[i].v >> e[i].w; // 输入每一条边 path.clear(); sort(e + 1, e + 1 + m, cmp); //按边权从大到小排序for(int i = 1; i <= m; i ++){int u = e[i].u, v = e[i].v, w = e[i].w;graph[u].push_back({v, w}), graph[v].push_back({u, w});if(find(u) == find(v)){ //加入这条边之后会产生新的环U = u, V = v, W = w; //此时w为最小边}else{merge(u, v); }}path.push_back(U);vis[U] = true;dfs(U);cout << W << " " << path.size() << "\n";for(auto it: path) {cout << it << " ";}cout << "\n";
}
int main()
{ios_base::sync_with_stdio(0);cin.tie(0);int t;cin >> t;while(t--){solve();}return 0;
}