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