Kruskal板子求调
  • 板块学术版
  • 楼主rb_tree
  • 当前回复4
  • 已保存回复4
  • 发布时间2024/10/12 20:26
  • 上次更新2024/10/12 22:06:31
查看原帖
Kruskal板子求调
740948
rb_tree楼主2024/10/12 20:26

rt,先跑一遍dijkstra判断是否是连通图,再用Kruskal求最小生成树,保证dijkstra没问题。

#include<cstdio>
#include<set>
#include<vector>
#include<algorithm>
#include<utility>
#include<queue>
#include<vector>
#include<cstring>
using namespace std;
inline int read()
{
    int x=0,w=1;
    char ch=0;
    while(ch<'0'||ch>'9')
    {
        if(ch=='-') w=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')
    {
        x=(x<<1)+(x<<3)+(ch^48);
        ch=getchar();
    }
    return x*w;
}
inline void write(int x) 
{
    if(x<0) 
    { 
        x=-x;
        putchar('-');
    }
    if(x>=10) write(x/10);
    putchar((x%10)^48);
}
int h[5005],nxt[400005],to[400005],cnt,val[400005],n,m;
inline void add_edge(int a,int b)
{
	to[++cnt]=b;
	val[cnt]=1;
	nxt[cnt]=h[a];
	h[a]=cnt;
	return;
}
struct edge
{
    int u,v,w;
};
bool operator<(const edge &x,const edge &y)
{
    return x.w<y.w;
}
vector<edge> a;
int fa[5005];
inline int father(int x)
{
    if(fa[x]==x) return x;
    return fa[x]=father(fa[x]);
}
inline void uunion(int x,int y)
{
    if(x!=y) fa[x]=fa[y];
    return;
}
inline set<edge> kruskal()
{
    for(int i=1;i<=n;i++) fa[i]=i;
    set<edge> result;
    sort(a.begin(),a.end());
    for(auto i:a)
    {
        const int fau=father(i.u),fav=father(i.v);
        if(fau!=fav) uunion(fau,fav),result.insert(i);
    }
    return result;
}
int dis[5005];
bool vis[5005]={};
inline bool dijkstra(int s)
{
	priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > > q;
	memset(dis,0x3f,sizeof(dis));
	q.push(make_pair(0,s));
	dis[s]=0;
	while(!q.empty())
	{
		int u=q.top().second;
		q.pop();
		if(vis[u]) continue;
		vis[u]=1;
		for(int i=h[u];i;i=nxt[i])
		{
			int v=to[i],w=val[i];
			if(dis[v]>dis[u]+w)
			{
				dis[v]=dis[u]+w;
				q.push(make_pair(dis[v],v));
			}
		}
	}
	for(int i=1;i<=n;i++)
	{
		if(dis[i]==0x3f3f3f3f) return 0;
	}
	return 1;
}
int main()
{
    n=read();
    m=read();
    for(int i=1;i<=m;i++) 
    {
        int u=read(),v=read(),w=read();
        a.push_back(edge{u,v,w});
        a.push_back(edge{v,u,w});
        add_edge(u,v);
        add_edge(v,u);
    }
    if(!dijkstra(1))
    {
        printf("orz");
        return 0;
    }
    set<edge> ans=kruskal();
    int aans=0;
    for(auto i=ans.begin();i!=ans.end();i++) aans+=(*i).w;
    write(aans);
    return 0;
}
2024/10/12 20:26
加载中...