題目:codevs-2597
題目:
時間限制: 1 s
空間限制: 128000 kb
題目等級 : ** gold
題解
2023年的芝加哥,出現了一群強盜。如果兩個強盜遇上了,那麼他們要麼是朋友,要麼是敵人。而且有一點是肯定的,就是:
我朋友的朋友是我的朋友;
我敵人的敵人也是我的朋友。
兩個強盜是同一團夥的條件是當且僅當他們是朋友。現在給你一些關於強盜們的資訊,問你最多有多少個強盜團夥。
輸入描述 input description
輸入檔案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是敵人。輸入資料保證不會產生資訊的矛盾。
輸出描述 output description
輸出檔案gangs.out只有一行,表示最大可能的團夥數。
樣例輸入 sample input
64e 1 4
f 3 5
f 4 6
e 1 2
樣例輸出 sample output
3資料範圍及提示 data size & hint
2<=n<=1000
1<=m<=5000
1<=p q<=n
這道題是一道並查集的題目。題目的重點在於,如何處理敵人的敵人也是朋友這種情況?朋友的朋友是朋友這很明顯因為他們在同乙個等價類裡面,可是敵人的敵人也是朋友就不那麼容易判定了。
對敵人的敵人直接進行合併:合併的辦法是,每乙個敵人的敵人都用乙個陣列來表示,並且進行動態地替換。那這時問題就來了,替換能夠對所有需要合併的關係進行合併嗎?會不會有遺漏的情況?
這個時候我們就需要拿起筆畫圖分析一下了:因為朋友的朋友也是朋友,所以當敵人的乙個敵人(因為他可能有多個敵人)被我當成朋友之後,雖然只合併了一次,但是其實這個敵人的所有敵人都是朋友了,因為朋友的朋友也是朋友,神奇吧,貼**~
改進之前:
#include #include #include using namespace std;
const int maxn=1005;
int n,m,x,y;
int tree[maxn],counts=0,ans=0;
struct t;
char c;
t s[100005];
int find(int aa)
int p=aa;
while(p!=t)
return t;
}void merge(int aa,int bb)
int main()
} for(int i=0;i改進之後:
#include #include #include using namespace std;
const int maxn=1005;
int n,m,x,y;
int friends[maxn],enemy[maxn],ans;
char c;
int find(int aa)
int p=aa;
while(p!=t)
return t;
}void merge(int a,int b)
}void mergeenemy(int a,int b)
int main()
cin>>m;
for(int i=0;i>c>>x>>y;
if(c=='f')
merge(x,y);
else
} cout<
好好學習,天天向上,加油~
Codevs 2597 團夥 並查集
2597 團夥 時間限制 1 s 空間限制 128000 kb 題目等級 gold 傳送門題目描述 description 1920年的芝加哥,出現了一群強盜。如果兩個強盜遇上了,那麼他們要麼是朋友,要麼是敵人。而且有一點是肯定的,就是 我朋友的朋友是我的朋友 我敵人的敵人也是我的朋友。兩個強盜是同...
Codevs 2597 團夥 並查集
2597 團夥 時間限制 1 s 空間限制 128000 kb 題目等級 gold 傳送門題目描述 description 1920年的芝加哥,出現了一群強盜。如果兩個強盜遇上了,那麼他們要麼是朋友,要麼是敵人。而且有一點是肯定的,就是 我朋友的朋友是我的朋友 我敵人的敵人也是我的朋友。兩個強盜是同...
並查集 1385 團夥 group
題目描述 在某城市裡住著n個人,任何兩個認識的人不是朋友就是敵人,而且滿足 1 我朋友的朋友是我的朋友 2 我敵人的敵人是我的朋友 所有是朋友的人組成乙個團夥。告訴你關於這n個人的m條資訊,即某兩個人是朋友,或者某兩個人是敵人,請你編寫乙個程式,計算出這個城市最多可能有多少個團夥?輸入 第1行為n和...