P1892 [BOI2003]团伙

斯德哥尔摩

2018-08-01 23:21:49

Personal

[P1892 [BOI2003]团伙](https://www.luogu.org/problemnew/show/P1892) 说实话,好久没有做过这么水的题了。。。 表示$NOI$有一题很像:[P2024 [NOI2001]食物链](https://www.luogu.org/problemnew/show/P2024) 然后就~~莫名其妙~~熟练地拆点: $x$表示$x$的朋友(这个容易吧。。。) $x+n$表示$x$的敌人(这个也不难) 如果$x$与$y$是朋友,合并$x$和$y$。 否则合并$x+n$和$y$,$y+n$和$x$($x$的敌人是$y$,$y$的敌人是$x$)。 注意合并的顺序。 附代码: ```cpp #include<iostream> #include<algorithm> #include<cstdio> #define MAXN 2010 using namespace std; int n,m,fa[MAXN]; inline int read(){ int date=0,w=1;char c=0; while(c<'0'||c>'9'){if(c=='-')w=-1;c=getchar();} while(c>='0'&&c<='9'){date=date*10+c-'0';c=getchar();} return date*w; } int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);} inline void uniun(int x,int y){x=find(x);y=find(y);if(x!=y)fa[y]=x;} void work(){ int ans=0; for(int i=1;i<=n;i++)if(find(i)==i)ans++; printf("%d\n",ans); } void init(){ char ch[2]; int x,y; n=read();m=read(); for(int i=1;i<=(n<<1);i++)fa[i]=i; for(int i=1;i<=m;i++){ scanf("%s",ch);x=read();y=read(); if(ch[0]=='F')uniun(x,y); else{uniun(x,y+n);uniun(y,x+n);} } } int main(){ init(); work(); return 0; } ```