Kruskal 44pts HELP TREE!

P3366 【模板】最小生成树

阿宁已被领养 @ 2022-09-26 19:40:43

记录如下,下了第三个测试点但是数据有点多看的眼都花了qwq

评测记录

数据还是不放了吧,太多了谁会手推五十个点的最小生成树啊qwq

代码如下

#include <iostream>
#include <cstdio>
#include <algorithm>
#define ll long long
using namespace std;
ll n,m,x,y,z,f[1000000],ans=0,qwq=0;
struct gs
{
    ll a,b,c;
}bian[1000000];
bool cmp(gs g,gs s)
{
    return g.c<s.c;
}
ll find(ll x)
{
    if(f[x]==x) return x; 
    else find(f[x]);
}
int main()
{
    scanf("%lld%lld",&n,&m);
    for(ll i=1;i<=n;i++) f[i]=i;
    for(ll i=1;i<=m;i++)
    {
        scanf("%lld%lld%lld",&x,&y,&z);
        bian[i].a=x;
        bian[i].b=y;
        bian[i].c=z;
    }
    sort(bian+1,bian+m+1,cmp);
    //cout<<"start"<<endl;
    for(ll i=1;i<=m;i++)
    {
        ll f1=find(bian[i].a),f2=find(bian[i].b);
        if(f1!=f2)
        {
            //cout<<bian[i].a<<' '<<bian[i].b<<" "<<f1<<' '<<f2<<endl;
            if(f1==bian[i].a) f1=f2;
            f[bian[i].a]=f1;
            f[bian[i].b]=f1;
            ans+=bian[i].c;
        }
    }
    for(ll i=1;i<=n;i++)//我想的是如果图不连通会有1+个根为自己的点,先纪录下来一个,再有多的就说明不连通了 
    {
        if(f[i]==i&&qwq==1)
        {
            printf("orz");
            return 0;
        }
        else if(f[i]==i) qwq++;
    }
    printf("%lld",ans);
    return 0;
}

不胜感激!!!!


by 8atemak1r @ 2022-09-26 19:48:17

@阿宁已被领养 判断无解你只需要在那个并查集里判断一下加进去的边是否等于 n-1 条就可以了,如果等于直接输出结果退出程序,如果整个 for 执行完了还没有结果那就无解


by 8atemak1r @ 2022-09-26 19:48:31

@阿宁已被领养 还有你这个并查集没看懂啊。


by 阿宁已被领养 @ 2022-09-26 19:50:22

@8atemak1r 并查集不是让很多节点的父亲是同一个就算是在同一个并查集里么


by 阿宁已被领养 @ 2022-09-26 19:51:35

@8atemak1r 可以设置一个记录加进去的边的变量ww在ans++的时候把ww+1最后与n+1比较判断么


by bktchizhi_fzh @ 2022-09-26 19:51:44

@阿宁已被领养 return x=find(f[x]);第十八行


by bktchizhi_fzh @ 2022-09-26 19:52:27

路径压缩


by Mr_ll @ 2022-09-26 20:08:22

#include <iostream>
#include <cstdio>
#include <algorithm>
#define ll long long
using namespace std;
ll n,m,x,y,z,f[10000],ans=0,qwq=0;
int cnt;
struct gs
{
    ll a,b,c;
}bian[1000000];
bool cmp(gs g,gs s)
{
    return g.c<s.c;
}
ll find(ll x)
{
    if(f[x]==x) return x; 
    else f[x]=find(f[x]);
}
int main()
{
    scanf("%lld%lld",&n,&m);
    for(ll i=1;i<=n;i++) f[i]=i;
    for(ll i=1;i<=m;i++)
    {
        scanf("%lld%lld%lld",&x,&y,&z);
        bian[i].a=x;
        bian[i].b=y;
        bian[i].c=z;
    }
    sort(bian+1,bian+m+1,cmp);
    //cout<<"start"<<endl;
    for(ll i=1;i<=m;i++)
    {
        ll f1=find(bian[i].a),f2=find(bian[i].b);
        if(f1!=f2)
        {
            //cout<<bian[i].a<<' '<<bian[i].b<<" "<<f1<<' '<<f2<<endl;
            //if(f1==bian[i].a) f1=f2;
            //f[bian[i].a]=f1;
            //f[bian[i].b]=f1;
            if(f1>f2) swap(f1,f2);
            f[f2]=f1;//有秩合并 
            ans+=bian[i].c;
            cnt++;//cnt记已加入多少边 
        }
        if(cnt==n-1) break; 
    }
//    for(ll i=1;i<=n;i++)//我想的是如果图不连通会有1+个根为自己的点,先纪录下来一个,再有多的就说明不连通了 
//    {
//        if(f[i]==i&&qwq==1)
//        {
//            printf("orz");
//            return 0;
//        }
//        else if(f[i]==i) qwq++;
//    }
    if(cnt!=n-1) puts("orz");
    else printf("%lld",ans);
    return 0;
}

by Mr_ll @ 2022-09-26 20:08:44

@阿宁已被领养


by 阿宁已被领养 @ 2022-09-26 20:14:48

@bktchizhi_fzh
@Mr_ll
@8atemak1r

已成功ACqwq

主要是find函数路径压缩和判断连通的问题

不胜感激orz


|