dfs,前向星,圖論知識(強連通,反向邊,橫邊,樹邊)
low的定義,tarjan過程模擬幾遍
有向圖n<=5000,找出所有的sink點,sink點是指sink點為起點經過的所有點都可以走回自己
scc後的dag中出度為0就能確保這一點,
否則,scca經過sccb,sccb中的點都無法走回scca的點,與sink的定義不符
63ms
#include#include#include#includeusing namespace std;
const int maxn=20005;
const int maxe=50005;
int low[maxn];
int dfn[maxn];
bool ins[maxn];
int sk[maxn];
int poi=0,idx=0,cnt=0;
int num=0;
int head[maxn];
int to[maxe*2];
int nxt[maxe*2];
int in[maxn];//入度
int ou[maxn];//出度
int scc[maxn];
void add(int u,int v)
void tarjan(int u)
else if(ins[v]) low[u]=min(low[u],dfn[v]);
} if(low[u]==dfn[u])
while(t!=u); }}
int main()
for(int i=1; i<=n; i++)
if(!dfn[i])tarjan(i);
for(int u=1; u<=n; u++)
}} int ans1=0; int ans2=0;
for(int i=1; i<=n; i++)
printf("\n");
}}
給有向圖n<=10000,m<=50000,問有多少個點使得該點被其他所有點經過若干路徑到達
原圖縮點後,僅存在乙個出度為0的點
(縮點後每個點都是強連通點集)的點集大小就是答案了
79ms
#include#include#include#includeusing namespace std;
const int maxn=20005;
const int maxe=50005;
int low[maxn];
int dfn[maxn];
bool ins[maxn];
int sk[maxn];
int poi=0,idx=0,cnt=0;
int num=0;
int head[maxn];
int to[maxe*2];
int nxt[maxe*2];
//int in[maxn];//入度
int ou[maxn];//出度
int scc[maxn];
int id[maxn];
void add(int u,int v)
void tarjan(int u)
else if(ins[v]) low[u]=min(low[u],dfn[v]);
} if(low[u]==dfn[u])
while(t!=u); }}
int main()
for(int i=1;i<=n;i++)
int ans=0;
for(int u=1;u<=n;u++)}}
int flag=0;
for(int i=1;i<=num;i++)
if(flag==1)
printf("%d\n",id[ans]);
else
printf("0\n");
} }
強連通專題
求割點 無向邊 所謂的割點,就是刪除某個點,圖便不連通了。poj 1523 include include include using namespace std const int mn 1111 struct edge edge mn 2 int dfn mn intlow mn int hea...
強連通分量 tarjan求強連通分量
雙dfs方法就是正dfs掃一遍,然後將邊反向dfs掃一遍。挑戰程式設計 上有說明。雙dfs 1 include 2 include 3 include 4 include 5 6using namespace std 7const int maxn 1e4 5 8 vector g maxn 圖的鄰...
強連通分量
對於有向圖的乙個頂點集,如果從這個頂點集的任何一點出發都可以到達該頂點集的其餘各個頂點,那麼該頂點集稱為該有向圖的乙個強連通分量。有向連通圖的全部頂點組成乙個強連通分量。我們可以利用tarjan演算法求強連通分量。define n 1000 struct edge e 100000 int ec,p...