关于 noip T2
  • 板块题目总版
  • 楼主Nt_Tsumiki
  • 当前回复2
  • 已保存回复2
  • 发布时间2023/11/19 18:07
  • 上次更新2023/11/19 18:16:05
查看原帖
关于 noip T2
420129
Nt_Tsumiki楼主2023/11/19 18:07

rt

并查集做法,大概就是先给每个 ii 赋个初始点,然后每次操作时,给 ii 重新赋一个点,统计答案是只看最后赋的点和初始点之间的关系。

#include <iostream>
#include <cstring>
#include <cstdio>

using namespace std;
int c,t,n,m,tot=1,p1,p2,p3;
int fa[800010],to[100001],be[100001];

int find(int x) { return x==fa[x]?x:fa[x]=find(fa[x]); }

int main() {
//	freopen("b.in","r",stdin);
//    freopen("b.out","w",stdout);
    scanf("%d%d",&c,&t);
    while (t--) {
        memset(fa,0,sizeof fa);
        tot=1;
        scanf("%d%d",&n,&m);
        p1=++tot,p2=++tot,p3=++tot;
        fa[p1]=p1,fa[p2]=p2,fa[p3]=p3;
        for (int i=1;i<=n;i++) be[i]=to[i]=(tot+=2),fa[tot]=tot,fa[tot^1]=tot^1;
        for (int i=1,x,y;i<=m;i++) {
            char ch;
            cin>>ch;
            scanf("%d",&x);
            to[x]=(tot+=2),fa[tot]=tot,fa[tot^1]=tot^1;
            if (ch=='T') {
                fa[find(to[x])]=find(p1);
                fa[find(to[x]^1)]=find(p2);
            } else if (ch=='F') {
                fa[find(to[x])]=find(p2);
                fa[find(to[x]^1)]=find(p1);
            } else if (ch=='U') {
                fa[find(to[x])]=find(p3);
                fa[find(to[x]^1)]=find(p3);
            } else if (ch=='+') {
                scanf("%d",&y);
                fa[find(to[x])]=find(to[y]);
                fa[find(to[x]^1)]=find(to[y]^1);
            } else {
                scanf("%d",&y);
                fa[find(to[x])]=find(to[y]^1);
                fa[find(to[x]^1)]=find(to[y]);
            }
        }
        int ans=0;
        for (int i=1;i<=n;i++) fa[find(to[i])]=find(be[i]),fa[find(to[i]^1)]=find(be[i]^1);
        for (int i=1;i<=n;i++) ans+=find(to[i])==find(to[i]^1);
        printf("%d\n",ans);
    }
    return 0;
}
2023/11/19 18:07
加载中...