图论--Tarjan求强联通分量
以下为普及+/提高- 难度
这篇我对Tarjan这个算法不作解释,不知道的戳这里.
tarjan这个算法在OI的图论题中很常用它在
然后就是一道模板题:
洛谷 P2863 [USACO06JAN]牛的舞会The Cow Prom
这题已经水到我无话可说了,真的是模板,但是就是一点要注意的,强联通分量必须点数>1才可以算。
code:
#include<bits/stdc++.h>
using namespace std;
struct edge{
int to,next;
}e[50001];
int n,m,tot,dfn_clock,num;
int head[10001];
int dfn[10001];
int low[10001];
int vis[10001];
int in[10001];
int s[10001],top;
void tarjan(int i){
vis[i]=1;
low[i]=dfn[i]=++dfn_clock;
s[++top]=i;
in[i]=1;
for(int j=head[i];j;j=e[j].next){
int u=e[j].to;
if(!vis[u]){
tarjan(u);
low[i]=min(low[i],low[u]);
}
else if(in[u]){
low[i]=min(low[i],dfn[u]);
}
}
if(dfn[i]==low[i]){
int cnt=0;
while(i!=s[top]){
in[s[top--]]=0;
cnt++;
}
cnt++;
in[s[top--]]=0;
if(cnt>=2)num++;
}
}
void addedge(int x,int y){
tot++;
e[tot].to=y;
e[tot].next=head[x];
head[x]=tot;
}
int main(){
scanf("%d %d",&n,&m);
for(int i=1;i<=m;i++){
int x,y;
scanf("%d %d",&x,&y);
addedge(x,y);
}
for(int i=1;i<=n;i++){
if(!vis[i]){
tarjan(i);
}
}
printf("%d",num);
return 0;
}
以后我还会对这篇作些补充。。
to be continued