hdu6370 werewolf 縮點 搜尋

2021-08-22 15:00:13 字數 1560 閱讀 2306

把圖畫一畫可以發現只能判斷鐵狼,沒有確定的村民,鐵狼會存在於乙個環中,這個環裡面如果只有乙個人被認為是狼,那麼他就是鐵狼,可以很容易看出這是乙個基環內向樹的樣子,所以就會發現,如果還有人說這個鐵狼是村民的話,那說這個狼是村民的人就是狼。於是就可以想到有些環是沒有用的環,如果有乙個環上的邊都是村民邊,那這個環沒有卵用,直接縮掉。至於如何搜答案,可以很快想到先確定環上的狼,然後向外擴充套件,於是就可以反向建圖,這時就是乙個基環外向樹的圖,並且如果只加村民邊的話,就形成了乙個樹的樣子(雖然有向圖這麼說很不嚴謹,但是想不到怎麼描述),並且每個點的入度最大為1,這樣就可以比較方便地暴力。(爆棧,改掉了乙個dfs)。

#include

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

using

namespace

std;

const

int maxn=100005;

struct edgee[maxn],e[maxn],e1[maxn],e2[maxn];

int dfn[maxn],low[maxn],index;

int head1[maxn],head2[maxn],head3[maxn],head4[maxn];

int s[maxn],top;

bool ins[maxn];

int col[maxn],numc;

int ecnt1,ecnt2,ecnt3,ecnt4;

void ins1(int u,int v)

void ins2(int u,int v)

void ins3(int u,int v)

void ins4(int u,int v)

void tarjan(int u)

else

if(ins[v]) low[u]=min(low[u],dfn[v]);

}if(dfn[u]==low[u])

}}int op,n;

char str[20];

int ans;

bool vis1[maxn];

bool flag[maxn];

void dfs(int u)}

for(int i=head3[u];i!=-1;i=e1[i].nxt)

vis1[u]=0;

}void bfs2(int u)

}}int ind[maxn];

int main()

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

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

if(!dfn[i]) tarjan(i);

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

}for(int i=head2[j];i!=-1;i=e[i].nxt)

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

if(!ind[col[i]])

for(int i=1;i<=n;i++) if(flag[col[i]])

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

}return

0;}

HDU6370 Werewolf 基環內向樹

hdu6370 werewolf 有 n 個人玩狼人殺,只有村民和狼人,每個人指定另乙個人並指出乙個身份,其中 村民是不會說謊的,狼人是有可能說謊的,問在所有情況下必然是狼人的人數和必然是村民的人數分別有多少 首先所有人都有可能說謊,所以不可能有人必然是村民 接下來我們考慮是否有人必然是狼人,我們考...

hdu4612 縮點 樹的直徑

題目大意 求乙個連通圖然後加一條邊使得橋的數目最少 題解思路 先把橋兩邊不是的點所有連通的點都縮成乙個點 然後把縮完的點構成一顆樹那麼再直徑的兩端加一條邊就是最優方案 注意 判斷重邊 題目鏈結 include include include include include include inclu...

最大流 縮點 HDU 3605 Escape

有n個人,m個星球。每個人都對不同的星球有自己的喜好,每個星球都有自己的容量。問能否讓所有的人都呆在自己喜歡的星球裡。1 n 100000 m 1 m 10 以為是套模板的題,一直tle,mle。看了大佬的 才明白這題需要縮點。因為最多有10個星球,所以最多有 include include inc...