zoukankan      html  css  js  c++  java
  • 【模拟7.25】回家(tarjan V-DCC点双连通分量的求法及缩点 求割点)模板题

    作为一道板子题放在第二题令人身心愉悦,不到一个小时码完连对拍都没打。

    关于tarjan割点的注意事项:

    1.在该板子中我们求的是V-DCC,而不是缩点,V-DCC最少有两个点组成,表示出掉一个块里的任意

    一点及其连边,联通性不变,所以割点只是顺便标记上low[to]>=dfn[x]的点,在以后的操作中

    将割点与联通块连边,所以最坏情况下所生点数(即原图为一条链)为2*n-2

    边数的话如没有明确给出一般为点数的8倍。

    ******(这题80分,就是数组开小,没加快读)*******

    2.我们在tarjan中每次分联通块时,while(top!=to),因为x可以属于多个联通块,所以我们

    不能将其弹栈,但可以将其放进块中

    3.else中low用dfn更新,因为不这样我们会将所有节点更新为1,这里不需要判断to是否为fa

    因为2.中的判断条件有>=;

    4.多测清空!!!!!!!!!!!!!!

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<string>
      5 #include<algorithm>
      6 #include<cmath>
      7 #include<stack>
      8 #include<map>
      9 #include<queue>
     10 #define ps push_back
     11 #define MAXN 405101
     12 #define ll long long
     13 using namespace std;
     14 int read()
     15 {
     16    char c=getchar();int x=0;
     17    while(c<'0'||c>'9')
     18    {
     19         c=getchar();
     20    }
     21    while(c>='0'&&c<='9')
     22    {
     23       x=(x<<1)+(x<<3)+(c^48);
     24       c=getchar();
     25    }
     26    return x;
     27 }
     28 int dfn[MAXN],low[MAXN],cut[MAXN],de;
     29 int vis[MAXN];
     30 int num_id,cnt;
     31 int belong[MAXN];
     32 vector<int>v[MAXN];
     33 stack<int>q;
     34 struct node{int to,n;}e1[MAXN*4],e2[MAXN*4];
     35 int head1[MAXN],head2[MAXN];int tot1,tot2;
     36 void add1(int u,int v)
     37 {
     38     e1[++tot1].to=v;e1[tot1].n=head1[u];head1[u]=tot1;
     39 }
     40 void add2(int u,int v)
     41 {
     42     e2[++tot2].to=v;e2[tot2].n=head2[u];head2[u]=tot2;
     43 }
     44 void tarjan(int x)
     45 {
     46    dfn[x]=low[x]=++de;vis[x]=1;q.push(x);
     47    int ss=0;
     48    for(int i=head1[x];i;i=e1[i].n)
     49    {
     50       int to=e1[i].to;
     51       if(dfn[to]==0)
     52       {         
     53           tarjan(to);
     54           low[x]=min(low[x],low[to]);
     55           if(low[to]>=dfn[x])
     56           {
     57               ss++;
     58               if(x!=1||ss>1)
     59               {
     60                   cut[x]=1;  
     61               }
     62               cnt++;
     63               int top=0;
     64               do
     65               {
     66                   top=q.top();q.pop();vis[to]=0;
     67                   v[cnt].ps(top);
     68               }
     69               while(to!=top);
     70               v[cnt].ps(x);
     71           }
     72       }  
     73       else 
     74           low[x]=min(low[x],dfn[to]);
     75    }
     76 }
     77 int n;
     78 int cut_kuan[MAXN];
     79 void init()
     80 {
     81     num_id=cnt;
     82     for(int i=1;i<=n;++i)
     83     {
     84         if(cut[i]==1)
     85         {
     86             belong[i]=++num_id;
     87             cut_kuan[num_id]=i;  
     88         }
     89     }
     90     for(int x=1;x<=cnt;++x)
     91     {
     92         for(int i=0;i<v[x].size();++i)
     93         {
     94             int now=v[x][i];
     95             if(cut[now]==1)
     96             {
     97                 add2(belong[now],x);
     98                 add2(x,belong[now]);
     99             }
    100             else 
    101             {
    102                 belong[now]=x;
    103             }
    104         }
    105     }
    106 }
    107 bool bian[MAXN];int fa[MAXN];
    108 void DFS(int x)
    109 {
    110    bian[x]=1;
    111    for(int i=head2[x];i;i=e2[i].n)
    112    {
    113        int to=e2[i].to;
    114        if(bian[to]==1)continue;
    115        fa[to]=x;
    116        DFS(to);
    117    }
    118 }
    119 int ans[MAXN];
    120 void find()
    121 {
    122     int x=belong[n];
    123     while(fa[x]!=0)
    124     {
    125         x=fa[x];
    126         if(cut_kuan[x]!=0&&x!=belong[1])
    127         {
    128            ans[++ans[0]]=cut_kuan[x];
    129         }
    130     }
    131 }
    132 int T,m;
    133 int main()
    134 {
    135     scanf("%d",&T);
    136     while(T--)
    137     {
    138          memset(head1,0,sizeof(head1));
    139          memset(head2,0,sizeof(head2));
    140          memset(cut,0,sizeof(cut));
    141          memset(dfn,0,sizeof(dfn));
    142          memset(low,0,sizeof(low));
    143          memset(vis,0,sizeof(vis));
    144          memset(belong,0,sizeof(belong));
    145          memset(fa,0,sizeof(fa));
    146          memset(bian,0,sizeof(bian));
    147          memset(ans,0,sizeof(ans));
    148          memset(cut_kuan,0,sizeof(cut_kuan));
    149          tot1=0;tot2=0;
    150          n=read();m=read();
    151          for(int i=1;i<=m;++i)
    152          {
    153              int x,y;
    154              //scanf("%d%d",&x,&y);
    155              x=read();y=read();
    156              add1(x,y);add1(y,x); 
    157          }
    158          tarjan(1);
    159          init();
    160          DFS(belong[1]);
    161          find();
    162          printf("%d
    ",ans[0]);
    163          sort(ans+1,ans+ans[0]+1);
    164          for(int i=1;i<=ans[0];++i)
    165          {
    166              printf("%d ",ans[i]);
    167          }
    168          cout<<endl;
    169          for(int i=1;i<=cnt;++i)
    170          {
    171              v[i].clear();
    172          }
    173          cnt=0;de=0;num_id=0;
    174     }
    175 }
    View Code
  • 相关阅读:
    Android Studio快速导入项目
    梦断代码阅读笔记01
    Python词云生成
    Python 数据处理
    Android studio 自定义Dialog
    Android studio Activity的跳转和数据传递
    Android studio Handler消息处理2
    2.9 react组件中使用key作为prop属性命名报错
    2.3 上下margin值合并
    2.2 快速认识虚拟dom
  • 原文地址:https://www.cnblogs.com/Wwb123/p/11248077.html
Copyright © 2011-2022 走看看