1. 程式人生 > >洛谷 P1892 團夥

洛谷 P1892 團夥

們的 void -- ngs gpo spa AI blank ios

              洛谷 P1892 團夥

題目描述

1920年的芝加哥,出現了一群強盜。如果兩個強盜遇上了,那麽他們要麽是朋友,要麽是敵人。而且有一點是肯定的,就是:

我朋友的朋友是我的朋友;

我敵人的敵人也是我的朋友。

兩個強盜是同一團夥的條件是當且僅當他們是朋友。現在給你一些關於強盜們的信息,問你最多有多少個強盜團夥。

輸入輸出格式

輸入格式:

輸入文件gangs.in的第一行是一個整數N(2<=N<=1000),表示強盜的個數(從1編號到N)。 第二行M(1<=M<=5000),表示關於強盜的信息條數。 以下M行,每行可能是F p q或是E p q(1<=p q<=N),F表示p和q是朋友,E表示p和q是敵人。輸入數據保證不會產生信息的矛盾。

輸出格式:

輸出文件gangs.out只有一行,表示最大可能的團夥數。

輸入輸出樣例

輸入樣例#1: 復制
6
4
E 1 4
F 3 5
F 4 6
E 1 2
輸出樣例#1: 復制
3

思路:並查集 難度:普及+/提高
//可讀性應該比較高吧。。。
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int n, m, tot;
int fa[1005], foe[1005], ff[1005];
//fa[]記錄每個人的上一層,foe[]記錄每個人的敵人,ff[]記錄有多少人是根 char c; int find(int x) { //尋找根節點 return fa[x]==x ? x : fa[x]=find(fa[x]); } void merge(int u, int v) { //merge 合並 int x = find(u), y = find(v); if(x == y) return ; fa[x] = y; tot--; } int main() { int maxn = -1; scanf("%d%d
", &n, &m); tot = n; //突然發現這個好像沒啥用qwq for(int i = 1; i <= n; i++) fa[i] = i; for(int i = 1; i <= m; i++) { cin >> c; int u, v; if(c == F) { //如果是朋友,直接合並 scanf("%d%d", &u, &v); merge(u, v); } if(c == E) { //分別尋找每個人是否有另一個敵人,然後進行合並 scanf("%d%d", &u, &v); if(foe[u] != 0) merge(v, foe[u]); if(foe[v] != 0) merge(u, foe[v]); foe[u] = v; foe[v] = u; } } for(int i = 1; i <= n; i++) { int t = find(fa[i]); ff[t]++; //尋找有哪些人作為根節點 if(t > maxn) maxn = t; } int sum = 0; for(int i = 1; i <= maxn; i++) if(ff[i] != 0) sum++; //計數 printf("%d", sum); return 0; }



洛谷 P1892 團夥