强连通分量
http://blog.csdn.net/xinghongduo/article/details/6195337
http://www.cnblogs.com/shadowland/p/5872257.html
http://blog.csdn.net/jeryjeryjery/article/details/52829142?locationNum=4&fps=1
https://www.byvoid.com/zht/blog/scc-tarjan/
题目
bzoj1051 缩点
被所有的牛认为受欢迎,也就意味着缩点之后,该牛所在的点的出度为0(否则其他点不可能全部通往该点)
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 const int Maxn=10000; 6 const int Maxe=50000; 7 int n,e,tot=0,num=0; 8 int top; 9 int Cnt[Maxn+50],Outdegree[Maxn+50]; 10 int Low[Maxn+50],Dfn[Maxn+50],Fir[Maxe+50],Stack[Maxn+50],Belong[Maxn+50]; 11 bool Vis[Maxn+50]; 12 struct Edge{ 13 int u,v,next; 14 }E[Maxe+50]; 15 16 int read(){ 17 char ch=getchar(); 18 int x=0,f=1; 19 while (ch<‘0‘||ch>‘9‘) { 20 if (ch==‘-‘) f=-1; 21 ch=getchar(); 22 } 23 while (ch>=‘0‘&&ch<=‘9‘){ 24 x=x*10+ch-‘0‘; 25 ch=getchar(); 26 } 27 return x*f; 28 } 29 void Insert(int x,int y){ 30 tot++; 31 E[tot].u=x; 32 E[tot].v=y; 33 E[tot].next=Fir[x]; 34 Fir[x]=tot; 35 } 36 void Tarjan(int u){ 37 Low[u]=Dfn[u]=++tot; 38 Stack[++top]=u; 39 Vis[u]=1; 40 for (int p=Fir[u];p!=-1;p=E[p].next){ 41 int v=E[p].v; 42 if (!Dfn[v]){ 43 Tarjan(v); 44 Low[u]=min(Low[u],Low[v]); 45 } 46 else if (Vis[v]) 47 Low[u]=min(Low[u],Dfn[v]); 48 } 49 if (Dfn[u]==Low[u]){ 50 num++; 51 int v=-1; 52 while (u!=v){ 53 v=Stack[top--]; 54 Belong[v]=num; 55 Cnt[num]++; 56 Vis[v]=0; 57 } 58 } 59 } 60 int main(){ 61 memset(Fir,-1,sizeof(Fir)); 62 n=read();e=read(); 63 for (int i=1;i<=e;i++){ 64 int u=read(),v=read(); 65 Insert(u,v); 66 } 67 memset(Low,0,sizeof(Low)); 68 memset(Dfn,0,sizeof(Dfn)); 69 memset(Vis,0,sizeof(Vis)); 70 for (int i=1;i<=n;i++) 71 if (!Dfn[i]) 72 Tarjan(i); 73 for (int i=1;i<=e;i++) 74 if (Belong[E[i].u]!=Belong[E[i].v]) 75 Outdegree[Belong[E[i].u]]++; 76 int res=0,ans=0; 77 for (int i=1;i<=num;i++) 78 if (Outdegree[i]==0){ 79 res++; 80 ans=i; 81 } 82 if(res==1) printf("%d\n",Cnt[ans]); 83 else printf("0\n"); 84 return 0; 85 }
poj1236 缩点
第一问求缩点之后入度为0的点数(只要入度不为0,就可从其他点处得到软件);
第二问答案为max(入度为零的点数,出度为0的点数)
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 const int Maxn=100; 6 const int Maxe=10000; 7 struct Edge{ 8 int from,u,v; 9 }E[Maxe]; 10 int n; 11 int tot_e=0,top=0,ans1,ans2,cnt=0; 12 int Fir[Maxn+50]={0},dfn[Maxn+50],low[Maxn+50],Stack[Maxn+100],Belong[Maxn+50]; 13 int time=0; 14 int V[Maxn+50],Indegree[Maxn+50],Outdegree[Maxn+50]; 15 int read(){ 16 int x=0,f=1; 17 char ch=getchar(); 18 while (ch<‘0‘||ch>‘9‘){ 19 if (ch==‘-‘) f=-1; 20 ch=getchar(); 21 } 22 while (ch>=‘0‘&&ch<=‘9‘){ 23 x=x*10+ch-‘0‘; 24 ch=getchar(); 25 } 26 return x*f; 27 } 28 void Insert(int u,int v){ 29 tot_e++; 30 E[tot_e].u=u;E[tot_e].v=v; 31 E[tot_e].from=Fir[u];Fir[u]=tot_e; 32 } 33 void Tarjan(int x){ 34 int y; 35 dfn[x]=low[x]=++time; 36 V[x]=1; 37 Stack[++top]=x; 38 for (int i=Fir[x];i;i=E[i].from){ 39 y=E[i].v; 40 if (!V[y]){ 41 Tarjan(y); 42 low[x]=min(low[x],low[y]); 43 } 44 if (V[y]==1) 45 low[x]=min(low[x],dfn[y]); 46 } 47 if (dfn[x]==low[x]){ 48 cnt++; 49 do{ 50 y=Stack[top--]; 51 Belong[y]=cnt;V[y]=2; 52 }while (y!=x); 53 } 54 } 55 int main(){ 56 n=read(); 57 memset(V,0,sizeof(V)); 58 for (int i=1;i<=n;i++){//build the graph 59 int j=read(); 60 while(j){ 61 Insert(i,j); 62 j=read(); 63 } 64 } 65 for (int i=1;i<=n;i++) 66 if (!V[i]) 67 Tarjan(i); 68 if (cnt==1){ 69 printf("1\n0"); 70 return 0; 71 } 72 for (int i=1;i<=tot_e;i++) 73 if (Belong[E[i].u]!=Belong[E[i].v]){ 74 Outdegree[Belong[E[i].u]]++; 75 Indegree[Belong[E[i].v]]++; 76 } 77 ans1=ans2=0; 78 for (int i=1;i<=cnt;i++){ 79 if (Indegree[i]==0) ans1++; 80 if (Outdegree[i]==0) ans2++; 81 } 82 printf("%d\n%d",ans1,max(ans1,ans2)); 83 return 0; 84 }
poj3177 边双联通分量
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 const int Maxn=5000; 6 const int Maxe=10000; 7 struct edge{ 8 int u,v,from; 9 }E[Maxe+100]; 10 int n,e; 11 int tot=0,T=0,ccnum=0; 12 int Fir[Maxn+50],dfn[Maxn+50],low[Maxn+50],cc[Maxn+50],Degree[Maxn+50]; 13 bool Is_cut[Maxn+50]={0}; 14 int read(){ 15 char ch=getchar(); 16 int x=0,f=1; 17 while (ch<‘0‘||ch>‘9‘){ 18 if (ch==‘-‘) f=-1; 19 ch=getchar(); 20 } 21 while (ch>=‘0‘&&ch<=‘9‘){ 22 x=x*10+ch-‘0‘; 23 ch=getchar(); 24 } 25 return x*f; 26 } 27 void Insert(int x,int y){ 28 tot++; 29 E[tot].u=x;E[tot].v=y; 30 E[tot].from=Fir[x];Fir[x]=tot; 31 } 32 void Tarjan(int x,int fa){ 33 dfn[x]=low[x]=++T; 34 for (int i=Fir[x];i;i=E[i].from) 35 if (E[i].v!=fa){ 36 int y=E[i].v; 37 if (!dfn[y]){ 38 Tarjan(y,x); 39 low[x]=min(low[x],low[y]); 40 if (low[y]>dfn[x]) Is_cut[i]=1,Is_cut[i%2?i+1:i-1]=1; 41 } 42 else low[x]=min(low[x],dfn[y]); 43 } 44 } 45 void dfs(int x,int fa){ 46 cc[x]=ccnum; 47 for (int i=Fir[x];i;i=E[i].from) 48 if (E[i].v!=fa&&!Is_cut[i]&&!cc[E[i].v]) 49 dfs(E[i].v,x); 50 } 51 int main(){ 52 n=read();e=read(); 53 memset(Fir,0,sizeof(Fir)); 54 for (int i=1;i<=e;i++){ 55 int u=read(),v=read(); 56 Insert(u,v); 57 Insert(v,u); 58 } 59 for (int i=1;i<=n;i++) 60 if (!dfn[i]) Tarjan(i,-1); 61 for (int i=1;i<=n;i++) 62 if (!cc[i]){ 63 ccnum++; 64 dfs(i,-1); 65 } 66 int ans=0; 67 for (int i=1;i<=tot;i++) 68 if (cc[E[i].u]!=cc[E[i].v]){ 69 Degree[cc[E[i].u]]++; 70 Degree[cc[E[i].v]]++; 71 } 72 for (int i=1;i<=ccnum;i++) 73 if (Degree[i]==2)ans++; 74 printf("%d",(ans+1)/2); 75 return 0; 76 return 0; 77 }
时间: 2024-10-22 00:30:34