hdu3639 強連通 縮點 tarjan演算法

2021-08-09 07:44:41 字數 1755 閱讀 7254

題意:投票:如果a投給b,b投給c,那麼c也會得到a的投票。現在要求誰的票最多,並輸出這些人的編號。

題解:跑tarjan求強連通分量,在強連通分量的隊伍中,每個點都是相互投票的。那麼對原圖進行縮點,然後反向建圖。選出入度為0的隊伍進行dfs,求出有隊伍投給了這個隊伍。將總人數求和減去自己即可。最後輸出在這個隊伍的人的編號。

**:

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define debug cout<<"aaa"<#define d(a) cout<#define mem(a,b) memset(a,b,sizeof(a))

#define ll long long

#define lson l,mid,root<<1

#define rson mid+1,r,root<<1|1

#define min_int (-2147483647-1)

#define max_int 2147483647

#define max_ll 9223372036854775807i64

#define min_ll (-9223372036854775807i64-1)

using

namespace

std;

const

int n = 100000 + 5;

const

int mod = 1000000000 + 7;

const

double eps = 1e-8;

int n,m,x[n],y[n];

int head[n],len;

int dfn[n],low[n],dfs_num;//dfn表示遍歷深度,low(u)為u或u的子樹能夠追溯到的最早的棧中節點的次序號

int color[n],col_num,num[n];//染色

intstack[n],vis[n],top;//棧和棧指標

int in[n],sum[n],cas=0;

struct edgenodeedge[n];

void add(int i,int j)

void init()

void tarjan(int x)

else

if(vis[temp])

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

top--;

}}int dfs(int u)

}return temp;

}void solve()

}mem(head,-1),mem(in,0),mem(sum,0),len=0;

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

}int ans=-1;

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

}printf("case %d: %d\n",++cas,ans-1);

bool flag=1;

for(int i=0;iif(sum[color[i]]==ans)

else}}

puts("");

}int main()

solve();

}return

0;}

hdu 3639 強連通分量 dfs

有 n 2 n 5000 個人,m 0 需要注意的是 support 是可以傳遞的,比如 a support b b support c,那麼,c 得到的 support 是 2 可以想到的是,列舉每個人得到的 support 的個數,這個做法是 o n 2 的。在 50 組資料的情況下,想要在 2...

hdu 2767 強連通縮點

補最少的邊成強連通圖。縮點後成dag,max即為所求。include include include define mn 20020 define me 200010 define mm a,b as void add e int i,int u,int v void tarjan int i el...

hdu 4635 強連通縮點

多校聯賽4的一道題,給乙個有向圖,問最多加多少條邊後仍然不是強聯通,以前總會遇到問最少加幾條邊讓圖成乙個強連通圖,比賽時自己就找到了答案,當時想著新增最多的邊後一定是將原來的圖連成兩個強連通分量,而兩個強連通分量間的邊最多是兩個聯通分量的點數之積,再加上每個聯通分量內部的點的邊數就是所有的邊數,再減...