zoukankan      html  css  js  c++  java
  • BZOJ5203 [NEERC2017 Northern] Grand Test 【dfs树】【构造】

    题目分析:

      首先观察可知这是一个无向图,那么我们构建出它的dfs树。由于无向图的性质我们可以知道它的dfs树只有返祖边。考虑下面这样一个结论。

      结论:若一个点的子树中(包含自己)有两个点有到它祖先的返祖边(不包括到它自己),

      首先我们证明S和T肯定在DFS树中是祖先关系,接着证明到T至少有一条返祖边,那么这个结论就是显然的了。

    代码:

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 
      4 const int maxn = 102000;
      5 
      6 int n,m;
      7 vector <int>g[maxn];
      8 
      9 int up[maxn],dep[maxn],wh[maxn],fa[maxn];
     10 int flag, from, to;
     11 
     12 void read(){
     13     scanf("%d%d",&n,&m);
     14     for(int i=1;i<=n;i++) g[i].clear();
     15     for(int i=1;i<=m;i++){
     16     int u,v; scanf("%d%d",&u,&v);
     17     g[u].push_back(v); g[v].push_back(u);
     18     }
     19 }
     20 
     21 int r1[maxn],num1;
     22 int r2[maxn],num2;
     23 int r3[maxn],num3;
     24 int md;
     25 stack <int> s;
     26 void print(int now){
     27     int pla = now;
     28     while(dep[pla] != to) r1[++num1] = pla,pla = fa[pla];
     29     r1[++num1] = pla;
     30     
     31     pla = md;
     32     while(dep[pla] != dep[now]) s.push(pla),pla = fa[pla];
     33     s.push(pla);
     34     while(!s.empty()){r2[++num2] = s.top();s.pop();}
     35     r2[++num2] = r1[num1];
     36     
     37     pla = wh[now];
     38     while(dep[pla] != dep[now]) s.push(pla),pla = fa[pla];
     39     s.push(pla);
     40     while(!s.empty()){r3[++num3] = s.top();s.pop();}
     41     pla = r1[num1];
     42     while(dep[pla] != up[now]) s.push(pla),pla = fa[pla];
     43     s.push(pla);
     44     while(!s.empty()){r3[++num3] = s.top();s.pop();}
     45     
     46     printf("%d %d
    ",r1[1],r1[num1]);
     47     printf("%d ",num1);for(int i=1;i<=num1;i++) printf("%d ",r1[i]);
     48     puts("");
     49     printf("%d ",num2);for(int i=1;i<=num2;i++) printf("%d ",r2[i]);
     50     puts("");
     51     printf("%d ",num3);for(int i=1;i<=num3;i++) printf("%d ",r3[i]);
     52     puts("");flag = 1;
     53 }
     54 
     55 void dfs(int now,int dp){
     56     dep[now] = dp; 
     57     for(int i=0;i<g[now].size();i++){
     58     int nxt = g[now][i];
     59     if(fa[now] == nxt) continue;
     60     if(flag) break;
     61     if(dep[nxt] == 0){
     62         fa[nxt] = now;
     63         dfs(nxt,dp+1); if(flag) break;
     64         if(up[nxt] >=  dep[now]) continue;
     65         if(up[now] >= 10000000) up[now] = up[nxt],wh[now] = wh[nxt];
     66         else{
     67         if(up[now] <= up[nxt]){
     68             from = now; to = up[nxt];md = wh[nxt];
     69         }else {
     70             from = now; to = up[now];up[now] = up[nxt];
     71             md = wh[now];wh[now]= wh[nxt];
     72         }
     73         print(from);
     74         }
     75     }else{
     76         if(dep[nxt] > dep[now]) continue;
     77         if(up[now] >= 10000000) up[now] = dep[nxt],wh[now] = now;
     78         else{
     79         if(up[now] <= dep[nxt]){
     80             from = now; to = dep[nxt];md = now;
     81         }else {
     82             from = now; to = up[now];up[now] = dep[nxt];
     83             md = wh[now];wh[now] = now;
     84         }
     85         print(from);
     86         }
     87     }
     88     }
     89 }
     90 
     91 void work(){
     92     flag = 0; from = 0; to = 0; num1 = num2 = num3 = 0;
     93     for(int i=0;i<=n;i++) wh[i] = 0,fa[i] = 0,dep[i] = 0,up[i] = 1e9;
     94     for(int i=1;i<=n;i++) if(!dep[i]) dfs(i,1);
     95     if(!flag){puts("-1");}
     96 }
     97 
     98 int main(){
     99     int cas; scanf("%d",&cas);
    100     while(cas--){
    101     read();
    102     work();
    103     }
    104     return 0;
    105 }
  • 相关阅读:
    调用google地图
    jQuery放大镜效果
    jQuery拖到效果
    jQuery制作相册
    jQuery ui插件用法
    jQuery写fadeTo方法
    jQuery实现动画效果
    jQuery的slideToggle方法
    控经纬度显示地图与卫星
    像百度那样的智能感知效果
  • 原文地址:https://www.cnblogs.com/Menhera/p/8900620.html
Copyright © 2011-2022 走看看