題目大意:給你n個點,m條單項邊,求可以和所有點聯通的點的個數。
注釋:n<=10,000,m<=50,000
想法:這題也是一道tarjan裸題,讓我來a掉吧!這題和愛在心中(愛在心中?猛戳)類似,只不過這題有坑... ...用panxf的模板a不掉這道題... ...為什麼呢?因為n的資料範圍,會mle。但是我們發現,這道題只需要求出強連通分量之中點的個數。所以,我們可以將原本記錄強連通分量的點的陣列f壓成一維。但是,我們不可以用鄰接矩陣來存邊了。同樣的,我們用鏈式前向星,保證不會mle。而且,我們在這裡需要作出乙個特判(不然會wa掉),就是如果存在乙個點,這個點入度和出度都為0,最後的答案一定為0,這是顯然的。下面,我們想怎樣才能正確的求出個數。同樣的,我們列舉出度為0的強連通分量,如果個數大於1,顯然個數為0。否則,就是這個強聯通分量的個數。
最後,附上醜陋的**... ...
1 #include 2 #include 3#define n 10010
4#define m 50010
5using
namespace
std;
6int
x[m],y[m];
7int
to[m],nxt[m],head[n],mid;
8int
z[n],deep[n],low[n],f[n];
9int
inwhat[n],chu[n];
10int
tot,top,ans;
11bool
v[n],isv1[n],isv2[n];
12int
inz[n];
13void add(int a,int b)//
存邊 14
19int
n;20
void tarjan(int x)//
tarjan
2130
if(deep[x]==low[x])
31while(t!=x);40}
41}42int
main()
4354
for(int i=1;i<=n;i++)
5558
if(n>=2)//
特判 5965}
66for(int i=1;i<=m;i++)
6770
int cnt=0;71
int middle=0;72
for(int i=1;i<=ans;++i) if(chu[i]==0) cnt++,middle=i;
73if(cnt>1)74
78else printf("
%d\n
",f[middle]);//
輸出即可。
79return0;
80 }
小結:tarjan是乙個o(n)的演算法,極其經典,正在getting中。
錯誤:在記錄出度的時候,不是chu[x[i]]++,而是chu[inwhat[x[i]]]++。
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
每一頭牛的願望就是變成一頭最受歡迎的牛。現在有 頭牛,給你 對整數 表示牛 認為牛 受歡迎。這種關係是具有傳遞性的,如果 認為 受歡迎,認為 受歡迎,那麼牛 也認為牛 受歡迎。你的任務是求出有多少頭牛被除自己之外的所有牛認為是受歡迎的。輸入格式 第一行兩個數 接下來 行,每行兩個數 意思是 認為 是...