1. 程式人生 > >BZOJ 1370: [Baltic2003]Gang團夥(luogu 1892)(種類並查集)

BZOJ 1370: [Baltic2003]Gang團夥(luogu 1892)(種類並查集)

col std max %d zoj pri get -s 題解

題面:

  bzoj題面有誤,還是看luogu的吧

  https://www.luogu.org/problemnew/show/P1892

題解:

  種類並查集。。

  因為有敵人的敵人是朋友這個條件,所以需要一個中轉點。。

  因此,將每個點拆成兩個點,一個是朋友點,另一個是敵人點。當讀到A與B是朋友時,就將A與B所對應的朋友點並集;當讀到兩個點是敵人的時候,就將A點所對應的敵人點與B所對應的朋友點並集,將A所對應的朋友點和B所對應的敵人點並集。

代碼:

#include<bits/stdc++.h>

using namespace std;

const
int maxn=3010; int fa[maxn],n,m,x,y,vis[maxn],ans; char ch[3]; int ffa(int x){ return fa[x]==x?x:fa[x]=ffa(fa[x]); } int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=2*n;i++) fa[i]=i; for(int i=1;i<=m;i++){ scanf("%s%d%d",ch,&x,&y);
if(ch[0]==F){ int fx=ffa(x),fy=ffa(y); if(fx!=fy) fa[fy]=fx; } else{ int fx=ffa(x),fy=ffa(y); int fxx=ffa(x+n),fyy=ffa(y+n); if(fx!=fyy) fa[fyy]=fx; if(fxx!=fy) fa[fxx]=fy; } } for
(int i=1;i<=n;i++) if(!vis[ffa(i)]) ans++,vis[ffa(i)]=1; printf("%d",ans); return 0; }

BZOJ 1370: [Baltic2003]Gang團夥(luogu 1892)(種類並查集)