HDU6370 Werewolf 基環內向樹

2022-08-18 18:24:12 字數 1518 閱讀 3295

hdu6370 werewolf

有\(n\)個人玩狼人殺,只有村民和狼人,每個人指定另乙個人並指出乙個身份,其中:村民是不會說謊的,狼人是有可能說謊的,問在所有情況下必然是狼人的人數和必然是村民的人數分別有多少

首先所有人都有可能說謊,所以不可能有人必然是村民

接下來我們考慮是否有人必然是狼人,我們考慮反推,即假設某個人是村民,是否產生矛盾

首先建圖,每個人向其指定的那個人連邊,如果指定為狼人,邊權是\(1\),否則邊權是\(0\)

可以發現,對於每一塊聯通塊,都是一棵基環內向樹,首先我們考慮環中是否有人必然是狼人

顯然如果環的權值是\(1\)的情況下才有可能必定存在狼人,在這個情況下,唯一被指定是狼人的那個人必定只能是狼人

然後考慮不在環上的人,如果指定了環上的狼人為村民的話,這也必然是狼人,而且這是有傳遞性的,也就是如果當前人指定乙個狼人是村民,那麼指向這個人的人,如果也指定是村民,那那個人也是狼人,直到有人指定其父節點是狼為止

view code

//#pragma gcc optimize("o3")

//#pragma comment(linker, "/stack:1024000000,1024000000")

#includeusing namespace std;

function____ = ();

const int maxn = 1e5+7;

int n, to[maxn], w[maxn], bel[maxn];

bool vis[maxn];

vectorg[maxn];

vectorpt[maxn];

void mark(int u, int id)

void dfs(int u, int &__count)

}int rua(int id)while(tp!=to[u]);

break;

}u = to[u];

}int __count = 0;

for(int x : vec) __count += w[x];

if(__count!=1) return 0;

for(int x : vec) if(w[x])

for(int x : pt[id]) vis[x] = false;

for(int x : vec) vis[x] = true;

dfs(u,__count);

return __count;

}void solve()

memset(bel+1,0,4*n);

memset(vis+1,0,n);

int id = 0;

for(int i = 1; i <= n; i++)

}int __count = 0;

for(int i = 1; i <= id; i++) __count += rua(i);

printf("%d %d\n",0,__count);

}int main()

HDU6370(思維 搜尋

題意 現在有n個人,每個人要麼是第一類 說的全是真話 要麼是第二類 說的可能是假話。每乙個人x都指認另乙個人y是第一類或第二類人。請問在所有合法的情況下,有多少人必定是第一類人 有多少人必定是第二類人?思路 首先題解送上 當然其實沒怎麼懂。我也不是這麼寫的 主要點 然後再xjb補充一下吧,以防以後看...

HDU 6370 狼人殺(並查集)

題目描述 有n個人在玩狼人殺,每個人有兩種身份,狼或者村民,村民必須要將真話,而狼可能講假話。現在每個人都會說出乙個除了自己外的乙個人身份,現在問你有多少個人確定是村民,有多少個人確定是狼人。題目分析 因為題目不排斥所有玩家都是狼人的情況 這一點都不符合遊戲規則好吧 因此題目中所有的人說的所有的話均...

hdu6370 werewolf 縮點 搜尋

把圖畫一畫可以發現只能判斷鐵狼,沒有確定的村民,鐵狼會存在於乙個環中,這個環裡面如果只有乙個人被認為是狼,那麼他就是鐵狼,可以很容易看出這是乙個基環內向樹的樣子,所以就會發現,如果還有人說這個鐵狼是村民的話,那說這個狼是村民的人就是狼。於是就可以想到有些環是沒有用的環,如果有乙個環上的邊都是村民邊,...