• 图的连通_Tarjan


    强连通分量

    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
    ",Cnt[ans]);
    83     else printf("0
    ");
    84     return 0;
    85 }
    View Code

    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
    0");
    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
    %d",ans1,max(ans1,ans2));
    83     return 0;
    84 }
    View Code

    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 }
    View Code
  • 相关阅读:
    【原创】express3.4.8源码解析之Express结构图
    【原创】backbone1.1.0源码解析之View
    【原创】javascript模板引擎的简单实现
    【原创】backbone1.1.0源码解析之Collection
    【原创】when.js2.7.1源码解析
    【原创】backbone1.1.0源码解析之Model
    【原创】backbone1.1.0源码解析之Events
    企业架构研究总结(35)——TOGAF架构内容框架之构建块(Building Blocks)
    企业架构研究总结(34)——TOGAF架构内容框架之架构制品(下)
    企业架构研究总结(33)——TOGAF架构内容框架之架构制品(上)
  • 原文地址:https://www.cnblogs.com/vincent-hwh/p/6746289.html
Copyright © 2020-2023  润新知