HAOI2006 受歡迎的牛

2022-09-19 02:42:14 字數 1269 閱讀 8849

首先對於乙個強聯通分量內的所有牛來說,他們彼此都認為對方受歡迎,且對於這個強聯通分量內的牛a來說,假設它認為不在這個強連通分量內的一頭牛b是受歡迎的,那麼這個強聯通分量內的所有牛都認為牛b受歡迎。

我們用tarjan演算法求一遍scc,把乙個scc縮成乙個點,並新增連線不同scc的邊,注意這條邊是一條反向邊,本來的邊由a->b,我們要新增的這條邊由scc[b]->scc[a],這樣做是為了方便之後的dfs,最後得到乙個dag。

接下來我們在這個dag上從所有入度為0的scc開始dfs,並記錄dfs過程中訪問到的scc個數記為cnt,如果dfs結束後cnt==scc_cnt,代表所有scc都認為這個scc是受歡迎的,則所有牛都認為這個scc內的牛是受歡迎的,累計牛的個數進答案即可。

我們只需要從入度為0的scc開始dfs,是因為假設有一條邊scc_a->scc_b,代表scc_b認為scc_a是受歡迎的,又因為圖是dag,所以scc_a一定不認為scc_b是受歡迎的,那麼scc_b一定無法達到被所有牛認為是受歡迎的條件,所以我們證明了入度不為0的scc一定不會是解。

// q.c

#include#include#include#include#include#includeusing namespace std;

const int m=10000+10;

int n,m,ans,cnt1,cnt2,dc,scc_cnt,scc[m],h1[m],h2[m],w[m],pre[m],low[m],in[m],out[m];

bool vis[m];

stacks;

struct edge

}ed1[m*5],ed2[m*5];

void add_edge(int a,int b,bool flag)

void dfs1(int u) else if(!scc[p.v])

low[u]=min(low[u],low[p.v]);

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

void dfs2(int u,int &d)

int main()

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

if(!pre[i]) dfs1(i);

for(int i=1;i<=n;i++) w[scc[i]]++;

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

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

if(!in[i])

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

return 0;

}

HAOI2006 受歡迎的牛

題目 分析 tarjan縮點。最後如果只有乙個出度為0的點,則答案就是這個點包含的牛數,否則為0.一開始最後統計的時候寫了dfs,後來發現是錯誤的,反例 include include include include include using namespace std const int tma...

HAOI2006 受歡迎的牛

這個就是強連通,計算出度為0的點就好 也沒森麼其它好講的啦 提交傳送們 description 每一頭牛的願望就是變成一頭最受歡迎的牛。現在有n頭牛,給你m對整數 a,b 表示牛a認為牛b受歡迎。這種關係是具有傳遞性的,如果a認為b受歡迎,b認為c受歡迎,那麼牛a也認為牛c受歡迎。你的任務是求出有多...

HAOI2006 受歡迎的牛

haoi2006 受歡迎的牛 每一頭牛的願望就是變成一頭最受歡迎的牛。現在有n頭牛,給你m對整數 a,b 表示牛 a 認為牛 b受歡迎。這種關係是具有傳遞性的,如果a認為b受歡迎,b認為c受歡迎,那麼牛a也認為牛c受歡迎。你的任務是求出有多少頭牛被所有的牛認為是受歡迎的。第1行兩個整數n,m 接下來...