Graph Theory - tarjan shrink point cut point (learning process)

First, begin by learning from the template title -        

    P3387 [template] point reduction

    Ideas:

      1. Why should shrink this question point? (When do I need reduced points)

       According to the meaning of the title, we just need to find the maximum point of a path right on the line, do not limit the number of points. Then consider a point on one of the rings is chosen, it is not a whole ring should have been selected, it must be very good, why not selected can be chosen. It is critical that the subject also allows us to repeat after one edge or a point, we do not need to consider the other. Thus the entire ring may actually be regarded as a point (a point where the option should be selected from other points)

- excerpt from the first chapter explanations Los Valley

      2. The strongly connected components condensing point -> be built edge DAG -> DPmax

  

 1 #include<cstdio>
 2 #include<queue>
 3 #include<vector>
 4 #include<cstring>
 5 #include<algorithm> 
 6 #define N 100010
 7 #define M 500010
 8 using namespace std;
 9 
10 struct node{
11     int from,to,next;
12 }edge[M];
13 queue < int > q;
14 vector < int > cd[N];        //出度 
15 vector  < int > rd[N];        //入度 
16 int ans[M],t,x,y,v,rds[N],u,n,m,sum,vis[N],d[N],dis[N];
17 int dfn[N],low[N],f[N],time,cnt,k;
18 int stack[N],head[M],visit[N],tot,id;
19 
20 void add(int x,int y){        //邻接表加边 
21     edge[++cnt].next=head[x];
22     edge[cnt].from=x;
23     edge[cnt].to=y;
24     head[x]=cnt;
25 }
26 
27 voidTarjan ( int X) {
 28      DFN [X] = Low [X] Time = ++;         // update 
29      Stack [ID ++] = X;         // handwritten stack 
30      Visit [X] = . 1 ;         // into stack 
31 is      for ( int I = head [X]; I; I = Edge [I] .next) {
 32          IF (! DFN [Edge [I] .to]) {         // is not updated to point 
33 is              Tarjan (Edge [I] .to);
 34 is              Low [X] = min (Low [X], Low [Edge [I] .to]);
 35          }
 36          the else {
 37 [              IF(Visit [Edge [I] .to])         // updated point 
38 is                  Low [X] = min (Low [X], DFN [Edge [I] .to]);
 39          }
 40      }
 41 is      IF (Low [ X] == DFN [X]) {         // note is not in the for loop 
42 is          TOT ++;         // strongly connected component number (condensing point number) 
43 is          the while ( . 1 ) {
 44 is              VIS [Stack [ID]] = TOT;         / / VIS record number condensing point 
45              DIS [TOT] + = D [Stack [ID]];         // weight reduction point value = strongly connected components accumulated weights 
46 is              Visit [Stack [ID]] = 0 , ID- ;         //Stack 
47              IF (X == Stack [+ ID . 1 ]) BREAK ;         // this communication block is completed shells 
48          }
 49      }
 50  }
 51 is  void TOPO () {         // topological sort 
52 is      for ( int I = . 1 ; I < TOT =; I ++) IF (RDS [I] == 0 ) q.push (I);         // into degrees (RDS) is 0, into the team 
53 is      the while ! ( q.empty ()) {
 54 is          int U = Q .front ();
 55          q.pop ();         // teams head out team
56 is          ANS [K ++] = U;         // ANS arranged in order of recording topologically point 
57 is          for ( int I = . 1 ; I <= CD [U] .size (); I ++) {         // CD [U]. size (): length cd [u] [] of 
58              V CD = [U] [I- . 1 ];         // because the vector is zero, so the reduction. 1 
59              RDS [V] -;         // the degree - 
60              IF (RDS [V] == 0 ) q.push (V);         // into degrees (RDS) is 0, into the team 
61 is          }
 62 is      }
 63 is  }
 64          
65  int main ()
 66  {
67     scanf("%d%d",&n,&m);
68     for(int i=1;i<=n;i++) scanf("%d",&d[i]);
69     for(int i=1;i<=m;i++) scanf("%d%d",&x,&y),add(x,y);
70         
71     for(int i=1;i<=n;i++)  if(!dfn[i]) tarjan(i);        // tarjan缩点 
72         
73     for(int i=1; I <= CNT; I ++) {         // the condensing point to build a good side -> the DAG 
74          IF (VIS [Edge [I]. from ] =! VIS [Edge [I] .to]) {
 75              X = VIS [edge [I]. from ], Y = VIS [edge [I] .to];         // build x-> y side 
76              RDS [Y] ++;         // Y into degrees ++ 
77              RD [Y ] .push_back (x);         // in the x-y of penetration into   
78              CD [x] .push_back (y);         // put into x y outdegree   
79          }
 80      }
 81      TOPO ();         // the DAG topology run on 
82      for( Int I = . 1 ; I <= TOT; I ++) {         // topologically sequence (no aftereffect) runs the DP 
83          int W = ANS [I];
 84          F [W] = DIS [W];
 85          for ( int J = . 1 ; J <= RD [W] .size (); J ++ )
 86              F [W] = max (F [W], F [RD [W] [J- . 1 ]] + DIS [W]) ;     // because the vector is zero, so the reduction. 1 
87      }
 88      
89      for ( int I = . 1 ; I <= TOT; I ++) max = SUM (F [I], SUM);         // final tally answer 
90      printf ( "%d",sum);
91     return 0;
92 }
View Code

 

     P3388 [template] point cut (top cut)

 1 #include<cstdio>
 2 #include<algorithm>
 3 #define N 100010
 4 using namespace std;
 5 struct node{
 6     int next,to;
 7 }edge[N*2];
 8 int n,m,dfn[N],cut[N],head[N],low[N],tot,cnt,id;
 9 
10 void add(int x,int y){
11     edge[++cnt].next=head[x];
12     edge[cnt].to=y;
13     head[x]=cnt;
14 }
15 
16 void  tarjan(int x,int root){        //割点 
17     int child=0;
18     dfn[x]=low[x]=++id;
19     for(int v,i=head[x];i;i=edge[i].next){
20         v=edge[i].to;
21         if(!dfn[v]){        //没有更新过的 
22             tarjan(v,root);
23             low[x]=min(low[x],low[v]);
24             if(low[v]>=dfn[x]&&x!=root) cut[x]=1;    // x is not a root cut point judgment conditions: Low [V]> = DFN [x] 
25              IF (x == the root) Child ++;         // if x is a root 
26 is          }
 27          the else  IF (! X = the root) Low [X] = min (Low [X], DFN [V]);
 28      }
 29      IF (Child> = 2 && the root == X) Cut [X] = . 1 ;         // X root of cut point judgment condition: YES two or more sub-trees 
30  }
 31 is  int main ()
 32  {
 33 is      Scanf ( " % D% D " , & n-, & m);
 34 is      for ( int U, V, I = . 1;i<=m;i++){
35         scanf("%d%d",&u,&v);
36         add(u,v),add(v,u);
37     }
38     for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i,i);
39     for(int i=1;i<=n;i++) if(cut[i]) tot++;
40     printf("%d\n",tot);
41     for(int i=1;i<=n;i++) if(cut[i]) printf("%d ",i);
42     return 0;
43 }
View Code

 

Guess you like

Origin www.cnblogs.com/RR-Jin/p/11617370.html