學習tarjan
受歡迎的牛
因為牛之間的關係具有傳遞性,所以找出有向圖中的強連通子圖,每個子圖中的牛一定互相喜歡。
$tarjan$縮點,只有出度為$0$的點(牛)才有可能受到其他所有牛的喜歡(圖中已無環)。
如果出度為$0$的點不止$1$個,那麼這幾個子圖中的牛都無法互相喜歡,輸出$0$。
#includeusingnamespace
std;
const
int n=1e4+5,m=5e4+5
;int
n,m,cnt,top,fro[n],s[n];
int tot,color,dfs[n],low[n],col[n],size[n],in
[n];
struct edgee[m];
void add(int x,int
y) ; fro[x]=cnt;
}void tarjan(int
u)
else
if(!col[v])
low[u]=min(low[u],dfs[v]);
}if(low[u]==dfs[u])
top--,size[color]++;
}}int
main()
間諜網路
題解
#includeusingnamespace
std;
const
int n=3e3+5,m=8e3+5
;int
tot,top,color,s[n],dfn[n],low[n],col[n];
int n,p,r,cnt,ans,fro[n],money[n],mo[n],in
[n];
struct edgee[m];
void add(int x,int
y) ; fro[x]=cnt;
}void tarjan(int
u)
else
if(!col[v])
low[u]=min(low[u],dfn[v]);
}if(dfn[u]==low[u])
top--;
}}int
main()
scanf("%d
",&r);
for(int i=1,u,v;i<=r;i++)
for(int i=1;i<=n;i++)
if(!dfn[i]&&money[i]<=2e4) tarjan(i);
for(int i=1;i<=n;i++)
if(!dfn[i]) return printf("
no\n%d
",i),0
;
for(int i=1;i<=n;i++)
for(int j=fro[i];j;j=e[j].nxt)
if(col[i]!=col[e[j].to]) in[col[e[j].to]]++;
for(int i=1;i<=color;i++)
if(!in[i]) ans+=mo[i];
printf(
"yes\n%d
",ans);
}
最大半聯通子圖
縮點後重新連邊,此時答案為新圖上最長鏈的個數。
用拓撲排序求出以各個點為終點的最長鏈的長度和個數,統計答案即可。
#includeusingnamespace
std;
const
int n=1e5+5,m=1e6+5
;int
n,m,x,c,k,f[n],g[n],q[n],ru[n],vis[n];
inttot,top,color,s[n],dfn[n],low[n],co[n],size[n];
intcnt,fro[n],fro2[n];
struct edgee[m],e2[m];
void add1(int x,int
y) ; fro[x]=cnt;
}void add(int x,int
y) ; fro2[x]=cnt;
ru[y]++;
}void tarjan(int
u)
else
if(!co[v])
low[u]=min(low[u],dfn[v]);
}if(dfn[u]==low[u])
top--,size[color]++;
}}void
rebuild()
void
dp()
while(h!=t)
else
if(f[u]+size[v]==f[v])
g[v]=(g[v]+g[u])%x;
vis[v]=u;}}
}int
main()
for(int i=1;i<=n;i++)
if(!dfn[i]) tarjan(i);
rebuild(),dp();
for(int i=1;i<=color;i++)
printf(
"%d\n%d
",k,c);
}
強連通分量 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...
強連通分量
在有向圖g中,如果兩個頂點間至少存在一條路徑,稱兩個頂點強連通 strongly connected 如果有向圖g的每兩個頂點都強連通,稱g是乙個強連通圖。非強連通圖有向圖的極大強連通子圖,稱為強連通分量 strongly connected components 下圖中,子圖為乙個強連通分量,因為...