luogu p3366 最小生成树模板

时间:2024-01-04 22:23:50

倒腾了一个小时  自己也没去看网上的

总算自己能写出来模板了

kruskal

//最小生成树  每次找最短的边
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = ;
int n,m;
ll res;
struct node
{
int st,e;
int cost;
}E[maxn];//建立边
int fa[maxn]; void init()
{
for(int i=;i<=n;i++)
fa[i] = i;
} int fi(int x)
{
return fa[x] == x? x : fa[x] = fi(fa[x]);
} void join(int x,int y)
{
int fx =fi(x),fy = fi(y);
if(fx != fy)
{
fa[fx] = fy;
}
} bool same(int x,int y)
{
return fi(x) == fi(y);
}
bool cmp(node a,node b)
{
return a.cost < b.cost;
} void solve()
{
init();
res = ;
sort(E+,E++m,cmp);
for(int i=;i<=m;i++)
{
node now = E[i];
if(same(now.st,now.e))
continue; //之前建立过边的 直接跳过
join(now.st,now.e);
res += E[i].cost;
}
} int main()
{
//freopen("in.txt","r",stdin);
while (~scanf("%d %d",&n,&m) )
{
for(int i=;i<=m;i++)
{
int x,y,v;
scanf("%d %d %d",&x,&y,&v);
E[i].st = x;
E[i].e = y;
E[i].cost = v;
}
solve();
bool flag = ;
for(int i=;i<=n;i++)
{
if(!same(,i))
{
flag =;break;
}
}
if(flag)
puts("orz");
else
cout<<res<<endl;
}
}

prim

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = ;
struct node {
int to,cost;
node (int t,int c):to(t),cost(c){}
bool operator<(const node& l)const
{
return cost > l.cost;
}
};
vector<node> E[maxn];
priority_queue<node> Q;
bool vis[maxn];
ll d[maxn];
int main ()
{
int n,m;
cin>> n>>m;
for(int i=;i<=m;i++)
{
int x,y,v;
scanf("%d %d %d",&x,&y,&v);
E[x].push_back({y,v});
E[y].push_back({x,v});
}
for(int i=;i<E[].size();i++)
Q.push(E[][i]);
d[] = ;vis[] = ;
ll res=;
while (Q.size())
{
node now = Q.top();
Q.pop();
if(vis[now.to])
continue;
res += now.cost;
vis[now.to] =;
for(int i=;i <E[now.to].size();i++)
{
Q.push(E[now.to][i]);
}
}
bool flag = ;
for(int i=;i<=n;i++)
{
if(!vis[i])
{
flag =;
break;
}
}
if(flag )
puts("orz");
else
cout<<res<<endl;
}