2017 07 14 Tarjan(受歡迎的牛)

2021-09-30 13:37:41 字數 1686 閱讀 9099

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define mm 50002

#define nn 10002

using

namespace

std;

int n,m,cnt,sign,top,tot;

intstack[mm],low[nn],first[nn],dfn[nn],belong[nn],outdegree[nn],num[nn];

bool vis[nn];

struct nodeedge[mm];

inline

void addedge(int x,int y)

inline

void tarjan(int x)

else

if (vis[v]) low[x]=min(low[x],dfn[v]);

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

}}int main()

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

if (!dfn[i])

tarjan(i);

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

if (belong[edge[i].from]!=belong[edge[i].to])

outdegree[belong[edge[i].from]]++;

int sum=0,x;

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

if (outdegree[i]==0)

if (sum==1) cout

cout

<<"0";

return

0;}

step 1:單向建邊

inline void addedge(int x,int y)
step 2:tarjan遍歷每乙個點,每個點只會遍歷一次,且只會退一次棧,因為乙個點只能在乙個強連通分量內存在

注意:

當v在棧中時,low[x]=min(low[x],dfn[v]);

當v不在棧中時,low[x]=min(low[x],low[v]);

inline

void tarjan(int x)

else

if (vis[v]) low[x]=min(low[x],dfn[v]);

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

}}

step 3:查詢每個強連通的出度

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

if (belong[edge[i].from]!=belong[edge[i].to])

outdegree[belong[edge[i].from]]++;

step 4 : 當且僅當只有乙個出度為1的強連通分量時存在答案,且答案為此強連通分量中牛的個數

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

if (outdegree[i]==0)

if (sum==1) coutreturn

0;

tarjan 受歡迎的牛

題 既然愛慕關係可以傳遞,那麼將互相可達的某幾個點縮成乙個點,就能簡化原圖了,那麼很自然想到tarjan求強連通分量 那麼就只需找到可以被所有縮點遍歷到的那個縮點 再輸出它所含的點數就行了 先用tarjan將所有聯通分量進行縮點,縮點後考慮出度為0的點的個數 1 個數大於1的時候,顯然不存在受歡迎的...

受歡迎的牛(tarjan)

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

受歡迎的牛 Tarjan

每一頭牛的願望就是變成一頭最受歡迎的牛。現在有 頭牛,給你 對整數 表示牛 認為牛 受歡迎。這種關係是具有傳遞性的,如果 認為 受歡迎,認為 受歡迎,那麼牛 也認為牛 受歡迎。你的任務是求出有多少頭牛被除自己之外的所有牛認為是受歡迎的。輸入格式 第一行兩個數 接下來 行,每行兩個數 意思是 認為 是...