版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yhf_naive/article/details/62039576
感想:
krusual算法(可能拼错了 逃。。。
注意点,判断是否唯一条件:如果在用krusual算法的时候运行到某条边时,发现至少有两条边权重相同且都可以加入,我们假设为1边和2边,然后你添加了1边,运行到最后结果你发现2边并不在最后的MST中,那你就想,如果我那个时候添加的是2边而不是1边,那应该有一个不一样的BST
故MST唯一的充要条件:如果MST唯一,那么运行到某步时,当某些权重相同的边都可以加入的时候,这些边一定要在最终的MST中
附:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
struct edge{
int n1,n2;
long long w;
int isin;//用于判断在某一步时是否可以选择加入
bool operator<(edge &a){
return w<a.w;
}
}e[513*263];
int isread[513];
int find(int i){
if(isread[i]==0)
return i;
return isread[i]=find(isread[i]);
}
void unino(int i,int j){//并查集
if(find(i)!=find(j))
isread[find(i)]=find(j);
}
int main(){
int N,M,i,j=0;long long wALL=0;int ISUNIQUE=0;
cin>>N>>M;
for(i=0;i<M;i++)
cin>>e[i].n1>>e[i].n2>>e[i].w;
sort(e,e+M);
for(i=0;i<M;i++){
if(find(e[i].n1)!=find(e[i].n2)){
j=i;
while(i!=M-1){
if(e[i+1].w==e[i].w){
if(find(e[i+1].n1)!=find(e[i+1].n2))
e[i+1].isin=1;
}
else break;
i++;
}
i=j;
unino(e[i].n1,e[i].n2);
wALL+=e[i].w;
}
else if(e[i].isin==1)
ISUNIQUE=1;
}
j=0;
for(i=1;i<=N;i++){
if(isread[i]==0)
j++;
}
if(j==1){
cout<<wALL<<endl;
if(ISUNIQUE)
cout<<"No"<<endl;
else
cout<<"Yes"<<endl;
}
else
cout<<"No MST"<<endl<<j<<endl;
}