題目描述:
有n個人在玩狼人殺,每個人有兩種身份,狼或者村民,村民必須要將真話,而狼可能講假話。現在每個人都會說出乙個除了自己外的乙個人身份,現在問你有多少個人確定是村民,有多少個人確定是狼人。
題目分析:
因為題目不排斥所有玩家都是狼人的情況(這一點都不符合遊戲規則好吧),因此題目中所有的人說的所有的話均有可能是假的。因此我們完全無法確定是否有人是村民。但是存在一定是狼人的情況。
當出現一種類似下圖的情況:
當我們發現有連續個點是有村民的邊,如點1,點2,點3,點4,點5,點6;而這些個連續的其中乙個點(如圖中的點6)有一條狼人邊連到了這些個連續的其他的點(如上圖練到了點1)。
此時,我們用反證法可以證明,倘若1號點是村民,則根據村民不會說謊的性質可以判斷出1到6號點全是村民,而根據村民不會說謊的性質,只能證明出1號點必為狼人。此時我們同時也可以發現,倘若1號點是狼人,則根據狼人會說謊的性質可知,指向1號點的村民邊則必定是狼人。
#include
#define maxn 100005
using
namespace std;
typedef pair<
int,
int>pll;
vector<
int>human[maxn]
;vectorwolf;
int far[maxn]
;int n;
void
init()
wolf.
clear()
;for
(int i=
0;i<=n;i++)}
intfind_f
(int x)
void
unit
(int x,
int y)
bool
same
(int x,
int y)
int ans=0;
void
dfs(
int x)
}int
main()
else
} ans=0;
int sz=wolf.
size()
;for
(int i=
0;icout<<
"0 "
<
}}
HDU3938 並查集 並查集
先按邊權值排個序,每次加入一條邊,用並查集,關鍵看懂題。include include include include using namespace std const int maxn 10010 int n,m,q struct edge edges maxn 5 inline int cmp...
hdu 拓撲排序 並查集
題目大意 有一些池塘,每乙個池塘都有乙個價值,現在想刪除一些池塘。有如下刪除條件 1 乙個池塘有兩個管道連線的不可以刪除。2 求最後剩下的為奇數環的池塘的價值。先用拓撲排序的思路將兩個一下連線的全刪除 只有用並查集統計數目 includeusing namespace std define ll l...
hdu 1198 並查集應用
其實可能是因為知道是用並查集做的原因啦,一下就看出題意了,明顯是並查集思想,每次輸入地圖中的一塊,檢測這一塊與它頂頭的那塊可不可以相通 如果可以合併集合 同理檢測其與它左邊的那一塊 最後遍歷一遍看有多少個根結點即要多少個水源 下面是 有點亂 include include define m 55 d...