受歡迎的蒜頭
tarjan演算法 + 縮點
先把乙個圖的各個強連通分量求出(使用tarjan演算法),接著用縮點的形式構建乙個有向無環圖(把各個強連通分量看成乙個點,利用點與點之間的關係,構建乙個強連通分量之間的有向圖,而且這個圖一定是無環的圖)
然後分析這個有向無環圖的出入度情況,出度為0,入度不為0,那這個強連通分量裡的點是可能被所有的點到達的
#include
#include
#include
using namespace std;
const
int max_n=
10001
;const
int max_m=
50001
;struct edge
edge
(int _u,
int _v,
int _n):u
(_u),v
(_v)
,next
(_n)
}e[max_m]
;int p[max_n]
;int belong[max_n]
,scc=0;
//統計各個點屬於那個連通分量,連通分量數
int idx=0;
//時間戳
int dfn[max_n]
,low[max_n]
;//dfn[i]表示點i被tarjan訪問的時間,low[i]表示i及i的子樹在棧**現的最早的時間。
int s[max_n]
,top=0;
//模擬棧
bool in_stack[max_n]
;//標記是否在棧中
int in[max_n]
,out[max_n]
;//統計縮點之後的有向無環圖圖的出入度情況
void
tarjan
(int u)
else
if(in_stack[v])}
if(dfn[u]
==low[u]
)while
(s[top]
!=u);}
}int
main()
memset
(dfn,0,
sizeof
(dfn));
memset
(in_stack,false,
sizeof
(in_stack));
for(
int i=
1;i<=n;
++i)}if
(scc==1)
//就乙個強連通分量,那任意兩個點都是可以互相到達的
memset
(in,0,
sizeof
(in));
memset
(out,0,
sizeof
(out));
for(
int i=
0;i++i)
}int std_scc=0;
for(
int i=
1;i<=scc;
++i)
std_scc=i;}}
int sum=0;
for(
int j=
1;j<=n;
++j)
printf
("%d\n"
,sum)
;return0;
//give me five
}
蒜頭君面試 計蒜客
蒜頭君來蒜廠面試的時候,曾經遇到這樣乙個面試題 給定 n nn 個整數,求裡面出現次數最多的數,如果有多個重複出現的數,求出值最大的乙個。當時可算是給蒜頭君難住了。現在蒜頭君來考考你。輸入格式 第一行輸入乙個整數 n 1 n 100000 n 1 le n le 100000 n 1 n 1000 ...
計蒜客 蒜頭君倒水
問題描述 蒜頭君倒了 2 杯熱水在杯子裡面,第一杯裡面有 a 毫公升,第二杯裡面有 b 毫公升。水太熱了,蒜頭君決定通過輪流倒水的方式來讓水冷下來。每次倒水蒜頭君把第一杯的 x 的水倒入第二杯,把第二杯的 y 的水倒入第一杯 蒜頭君有奇特的方法,能讓這一過程是同是發生的,沒有先後之分 蒜頭君一直重複...
計蒜客 蒜頭君回家
樣例輸入 8 10 p.p t s 樣例輸出 思路用兩次bfs,第一次計算出起點到p的距離,第二次計算出t到p的距離,然後迴圈取最小值。但是wa了很多次,找了很久,發現是vis判斷的問題,導致乙個資料更新多次。ac include include include include using name...