POJ - 1679——(次小生成树)
作者:互联网
总结
开始写了一个n2,但是总感觉可以优化的,然后去群里瞎逼逼了一会,果然学到了,一次克鲁斯卡尔就可以搞定了,O(mlogm)。
理论
边权相等的边,边两点不同的并查集的边数<=所在不同的并查集个数-1
保证最小生成树唯一
题目链接
//#pragma GCC optimize(2)
#include<vector>
#include<set>
#include<map>
#include<stack>
#include<queue>
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cmath>
#include<time.h>
#include<stdio.h>
//typedef long long ll;
//#define ull unsigned long long
#define int long long
#define F first
#define S second
#define endl "\n"//<<flush
#define eps 1e-6
#define lowbit(x) (x&(-x))
#define PI acos(-1.0)
#define inf 0x3f3f3f3f
#define MAXN 0x7fffffff
#define INF 0x3f3f3f3f3f3f3f3f
#define pa pair<int,int>
#define ferma(a,b) pow(a,b-2)
#define pb push_back
#define all(x) x.begin(),x.end()
#define memset(a,b) memset(a,b,sizeof(a));
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
using namespace std;
void file()
{
#ifdef ONLINE_JUDGE
#else
freopen("cin.txt","r",stdin);
// freopen("cout.txt","w",stdout);
#endif
}
const int N=1e6+5;
int fat[N];
int find(int x)
{
return fat[x]==x?x:fat[x]=find(fat[x]);
}
struct node
{
int x,y,v;
void input(){cin>>x>>y>>v;}
bool operator<(const node &b)const{return v<b.v;}
} s[N];
signed main()
{
IOS;
// file();
int t;
cin>>t;
while(t--)
{
int n,m,ans=0,sum=0;
cin>>n>>m;
for(int i=0; i<m; i++)
s[i].input();
sort(s,s+m);
for(int i=1; i<=n; i++)
fat[i]=i;
for(int i=0; i<m; i++)
{
int j=i;
while(j+1<m&&s[j+1].v==s[i].v)
j++;
for(int k=i;k<=j;k++)
if(find(s[k].x)!=find(s[k].y))sum++;
for(int k=i;k<=j;k++)
{
int tx=find(s[k].x),ty=find(s[k].y);
if(tx!=ty)
fat[tx]=ty,ans+=s[k].v;
}
i=j;
}
if(sum>=n)
cout<<"Not Unique!"<<endl;
else
cout<<ans<<endl;
}
return 0;
}
标签:int,fat,cin,long,生成,POJ,1679,include,define 来源: https://blog.csdn.net/weixin_44224825/article/details/104819653