HDU 6038 Function(強連通分量)

2021-08-04 09:19:16 字數 1522 閱讀 8427

#include

#include

#include

using

namespace

std;

/*tarjan演算法

對於a和b分別建圖,讓i與ai連邊、i與bi連邊

計算圖強連通分量的個數cnt_a,cnt_b和各個強連通分量包含點的個數num_a,num_b

如果num_a>=num_b&&num_a%num_b==0 說明值域中num_b個數可以代入num_a個遞推式

*/const

int maxn=1e5+5;//點數

const

int mod=1e9+7;

struct edge

edge[maxn];

int head[maxn],tot;

//belong 陣列的值是1~scc

int low[maxn],dfn[maxn],stack[maxn],belong[maxn];

int index,top;

int scc;//強連通分量的個數

bool instack[maxn];

int num[maxn];//各個強連通分量包含點的個數,陣列編號1~scc

int n,m;

int num_a[maxn];

int num_b[maxn];

int cnt_a,cnt_b;

void addage(int u,int v)

void tarjan(int u)

else

if(instack[v]&&low[u]>dfn[v])

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

while(v!=u);

}}void solve(int n)

}}void init()

int main()

solve(n);

cnt_a=scc;

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

init();

for(int i=0;iscanf("%d",&x);

addage(i,x);

}solve(m);

cnt_b=scc;

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

int ans=1;

int tmp=0;

//printf("cnt_a=%d cnt_b=%d\n",cnt_a,cnt_b);

for(int i=0;i0;//有cnt_a個遞推式時,函式可以有tmp個

for(int j=0;j//printf("a=%d b=%d\n",num_a[i],num_b[j]);

if(num_a[i]>=num_b[j]&&num_a[i]%num_b[j]==0)

}//printf("tmp=%d\n",tmp);

ans=(ans*tmp)%mod;

}printf("case #%d: %d\n",kase++,ans);

}return

0;}

HDU 6038 Function 找迴圈節

這題比賽的時候題意就看了半天,看到最後看懂了,感覺是找迴圈但是不知道怎麼處理,也沒再做。比完賽對著標程看才明白這題的做法。題意是說有兩個陣列a,b,他們之間滿足關係式 因為要求找出相互之間的對應關係的種數,再通過例子,便想著是要找迴圈來找出對應關係。因為a可以和f函式的順序構成關係,所以以a為固定,...

hdu 4612 強連通分量

題意 有一些小島,這些小島上有一些邊,讓你加一條邊,使得原先的那些邊的橋數最少。做法 1,把小島為點,連線小島的為邊建圖。2,求出圖中的所有強聯通分量 3,把所有的強聯通分量看成乙個點建樹。4,求樹的直徑,新加的那條邊應該在直徑的兩邊,這樣才能使得圖中的橋最小。pragma comment link...

HDU 3072 強連通分量

題目鏈結 題目大意 為乙個有向連通圖加邊。使得整個圖全連通,有重邊出現。解題思路 先用tarjan把強連通分量縮點。由於整個圖肯定是連通的,所以列舉每一條邊,記錄到非0這個點所在連通分量的最小cost。一共需要累加cnt 1個連通分量的cost。在tarjan過程中的重邊,可以用鏈式前向星結構解決。...