跑出最小生成树后,记录MST中的每条边,然后枚举MST中的每条边,再跑n-1次MST,如果新的MST大小和原来的一样并且 MST边数要为n-1,那么则不唯一
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <string>
#include <set>
#include <vector>
#include <map>
#include <sstream>
#include <queue>
#define LL long long
const LL INF = 0x3f3f3f3f;
const int maxn = 250000 + 5;
using namespace std;
vector<int> mst;
int fa[maxn];
int RANK[maxn];
struct Edge{
int from, to, c;
Edge(){}
Edge(int ff, int tt, int cc):from(ff),to(tt),c(cc){}
bool operator < (const Edge &p) const{
return c < p.c;
}
}edge[maxn];
void init(){
for(int i=0; i<maxn; i++){
fa[i] = i;
RANK[i] = 0;
}
}
int FIND(int x){
if(fa[x] == x) return x;
return fa[x] = FIND(fa[x]);
}
void UNITE(int x, int y){
x = FIND(x);
y = FIND(y);
if(x == y) return;
if(RANK[x] < RANK[y]){
fa[x] = y;
RANK[y] ++;
}
else {
fa[y] = x;
RANK[x] ++;
}
}
bool SAME(int x, int y){
return FIND(x) == FIND(y);
}
int main(){
init();
mst.clear();
int n,m;
scanf("%d%d",&n,&m);
for(int i=0; i<m; i++){
scanf("%d%d%d",&edge[i].from,&edge[i].to,&edge[i].c);
}
sort(edge,edge+m);
int mstans = 0;
int cnt = 0;
for(int i=0; i<m; i++){
Edge e = edge[i];
int u = e.from, v = e.to, c = e.c;
if(SAME(u,v)) continue;
UNITE(u,v);
mstans += c;
mst.push_back(i);
cnt++;
}
if(cnt != n-1){
printf("No MST\n");
printf("%d\n",n-cnt);
}
else{
printf("%d\n",mstans);
bool flag = false;
int ans = 0;
int sum = 0;
for(int i=0; i<mst.size(); i++){
init();
ans = 0;
sum = 0;
for(int j=0; j<m; j++){
if(mst[i] == j) continue;
Edge e = edge[j];
int u = e.from, v = e.to, c = e.c;
if(SAME(u,v)) continue;
UNITE(u,v);
ans += c;
sum++;
}
if(ans == mstans && sum == n-1){
flag = true;
break;
}
}
if(flag) printf("No\n");
else printf("Yes\n");
}
}