• 【模拟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
  • 相关阅读:
    How to function call using 'this' inside forEach loop
    jquery.validate.unobtrusive not working with dynamic injected elements
    Difference between jQuery.extend and jQuery.fn.extend?
    Methods, Computed, and Watchers in Vue.js
    Caution using watchers for objects in Vue
    How to Watch Deep Data Structures in Vue (Arrays and Objects)
    Page: DOMContentLoaded, load, beforeunload, unload
    linux bridge
    linux bridge
    EVE-NG网卡桥接
  • 原文地址:https://www.cnblogs.com/Wwb123/p/11248077.html
Copyright © 2020-2023  润新知