社区讨论

求助简单并查集卡常

P1955[NOI2015] 程序自动分析参与者 6已保存回复 7

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
7 条
当前快照
1 份
快照标识符
@mmdhcsrz
此快照首次捕获于
2026/03/05 21:07
5 天前
此快照最后确认于
2026/03/07 20:20
3 天前
查看原帖
rt,最近在切水题,被水题切了
做法是先处理相等情况,然后不等情况与相等出现矛盾就无法满足,否则可以满足。
CPP
#include<bits/stdc++.h>
using namespace std;
#define MAXN 100000
int t,n;
map<int,int> to;
int p;
int fa[MAXN*2+10];
int x[MAXN+10],y[MAXN+10];
bool e[MAXN+10];
int f(int x){return fa[x]==x?x:f(fa[x]);}
signed main()
{
    //freopen("P1955_2.in","r",stdin);freopen("task.out","w",stdout);
    ios::sync_with_stdio(0);cin.tie(0);
    cin>>t;
    for(;t--;)
    {
        cin>>n;
        for(int i=1;i<=n;i++)
        {
            cin>>x[i]>>y[i]>>e[i];
            to[x[i]]=to[y[i]]=0;
        }
        for(auto &i:to)i.second=++p;
        for(int i=1;i<=n;i++)x[i]=to[x[i]],y[i]=to[y[i]];
        for(int i=1;i<=p;i++)fa[i]=i;
        for(int i=1;i<=n;i++)if(e[i])fa[f(x[i])]=f(y[i]);
        bool flg=1;
        for(int i=1;i<=n;i++)
        {
            if(!e[i])
            {
                if(f(x[i])==f(y[i]))
                {
                    cout<<"NO\n";
                    flg=0;
                    break;
                }
            }
        }
        if(flg)cout<<"YES\n";
        p=0;
    }
}
CPP
#include<bits/stdc++.h>
using namespace std;
#define MAXN 200000
int t,n;
map<int,int> to;
int p;
int fa[MAXN*2+10];
int x[MAXN+10],y[MAXN+10];
bool e[MAXN+10];
int f(int x)
{
    for(;fa[x]!=x;x=fa[x]);
    return x;
}
signed main()
{
    //freopen("P1955_2.in","r",stdin);freopen("task.out","w",stdout);
    ios::sync_with_stdio(0);cin.tie(0);
    cin>>t;
    for(;t--;)
    {
        cin>>n;
        for(int i=1;i<=n;i++)
        {
            cin>>x[i]>>y[i]>>e[i];
            to[x[i]]=to[y[i]]=0;
        }
        for(auto &i:to)i.second=++p;
        for(int i=1;i<=n;i++)x[i]=to[x[i]],y[i]=to[y[i]];
        for(int i=1;i<=p;i++)fa[i]=i;
        for(int i=1;i<=n;i++)if(e[i])fa[f(x[i])]=f(y[i]);
        bool flg=1;
        for(int i=1;i<=n;i++)
        {
            if(!e[i])
            {
                if(f(x[i])==f(y[i]))
                {
                    cout<<"NO\n";
                    flg=0;
                    break;
                }
            }
        }
        if(flg)cout<<"YES\n";
        to.clear();
        p=0;
    }
}
明明没开long long,并查集常数一般也跑不满吧。,放VS Code上用Code Runner运行一下点8跑了多次都是6.4s左右。
CPP
#include<bits/stdc++.h>
using namespace std;
char buf[1<<17],*p1,*p2;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<16,stdin),p1==p2)?EOF:*p1++)
void qread(int &n)
{
    n=0;
    char c=0;
    bool f=0;
    for(;c<'0'||'9'<c;c=getchar())f=f|(c=='-');
    if(f)for(;'0'<=c&&c<='9';n=n*10+48-c,c=getchar());
    else for(;'0'<=c&&c<='9';n=n*10+c-48,c=getchar());
}
void qwrite(int n)
{
    char output[12]={};
    int top=0;
    if(n==0){putchar('0');return;}
    if(n<0){putchar('-');n=-n;}
    for(;n;output[40-(++top)]=n%10+48,n/=10);
    fwrite(output+40-top,1,top,stdout);
}
#define MAXN 100000
int t,n;
map<int,int> to;
int p;
int fa[MAXN*2+10];
int x[MAXN+10],y[MAXN+10];
int e[MAXN+10];
int f(int x)
{
    for(;fa[x]!=x;x=fa[x]);
    return x;
}
signed main()
{
    //freopen("P1955_8.in","r",stdin);freopen("task.out","w",stdout);
    //ios::sync_with_stdio(0);cin.tie(0);
    qread(t);
    for(;t--;)
    {
        qread(n);
        for(int i=1;i<=n;i++)
        {
            qread(x[i]),qread(y[i]),qread(e[i]);
            to[x[i]]=0;
            to[y[i]]=0;
        }
        for(auto &i:to)i.second=++p;
        for(int i=1;i<=n;i++)x[i]=to[x[i]],y[i]=to[y[i]];
        for(int i=1;i<=p;i++)fa[i]=i;
        for(int i=1;i<=n;i++)if(e[i])fa[f(x[i])]=f(y[i]);
        bool flg=1;
        for(int i=1;i<=n;i++)
        {
            if(!e[i])
            {
                if(f(x[i])==f(y[i]))
                {
                    printf("NO\n");
                    flg=0;
                    break;
                }
            }
        }
        if(flg)printf("YES\n");
        to.clear();
        p=0;
    }
}
有没有什么改动小的方法能卡过去,不太想改离散化,map常数比排序+lower_bound离散化常数大 很多 吗?
是不是我必须再加上启发式合并了、

回复

7 条回复,欢迎继续交流。

正在加载回复...