并查集模板题。对于敌对关系有两种解决方案,
一是另开一个数组存敌人,这个数组无需预处理但是处理关系时需要特判,小心与0的合并;
还有一种巧妙的办法是把fa[]数组开两倍空间,fa[i]的敌人设为fa[i+n],需要预处理然而处理关系时直接合并就行了。
code:
1 #include<iostream> 2 #include<cstdio> 3 4 using namespace std; 5 6 const int Maxn = 1010; 7 8 int fa[Maxn],ene[Maxn],vis[Maxn]; 9 int find(int x){ 10 if(fa[x] == x)return x; 11 return fa[x] = find(fa[x]); 12 } 13 int n,m,p,q,ans; 14 char ch; 15 16 int main(){ 17 cin >> n >> m; 18 for(int i = 1;i <= n;i++)fa[i] = i; 19 for(int i = 1;i <= m;i++){ 20 cin >> ch >> p >> q; 21 if(ch == 'E'){ 22 if(ene[p])fa[find(q)] = find(ene[p]); 23 else ene[p] = find(q); 24 if(ene[q])fa[find(p)] = find(ene[q]); 25 else ene[q] = find(p); 26 } 27 else fa[find(p)] = find(q); 28 } 29 for(int i = 1;i <= n;i++)if(!vis[find(i)])vis[find(i)] = 1,ans++;//vis[find(i)] 30 cout << ans; 31 return 0; 32 }
1 #include<iostream> 2 #include<cstdio> 3 4 using namespace std; 5 6 const int Maxn = 1010; 7 int fa[Maxn<<1]; 8 9 int find(int x){ 10 if(fa[x] == x)return x; 11 return fa[x] = find(fa[x]); 12 } 13 14 int n,x,y,m,ans; 15 char ch; 16 17 int main(){ 18 cin >> n >> m; 19 for(int i = 1;i <= n<<1;i++)fa[i] = i; 20 for(int i = 1;i <= m;i++){ 21 cin >> ch >> x >> y; 22 if(ch == 'E'){ 23 fa[find(x+n)] = find(y); 24 fa[find(y+n)] = find(x); 25 } 26 else fa[find(x)] = find(y); 27 } 28 for(int i = 1;i <= n;i++)if(fa[i] == i)ans++; 29 cout << ans; 30 return 0; 31 }