zoukankan      html  css  js  c++  java
  • [51nod] 1076 2条不相交的路径 #边双联通分量

    1076 2条不相交的路径

    基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题
     
    给出一个无向图G的顶点V和边E。进行Q次查询,查询从G的某个顶点V[s]到另一个顶点V[t],是否存在2条不相交的路径。(两条路径不经过相同的边)
    (注,无向图中不存在重边,也就是说确定起点和终点,他们之间最多只有1条路)
     
    Input
    第1行:2个数M N,中间用空格分开,M是顶点的数量,N是边的数量。(2 <= M <= 25000, 1 <= N <= 50000)
    第2 - N + 1行,每行2个数,中间用空格分隔,分别是N条边的起点和终点的编号。例如2 4表示起点为2,终点为4,由于是无向图,所以从4到2也是可行的路径。
    第N + 2行,一个数Q,表示后面将进行Q次查询。(1 <= Q <= 50000)
    第N + 3 - N + 2 + Q行,每行2个数s, t,中间用空格分隔,表示查询的起点和终点。
    Output
    共Q行,如果从s到t存在2条不相交的路径则输出Yes,否则输出No。
    Input示例
    4 4
    1 2
    2 3
    1 3
    1 4
    5
    1 2
    2 3
    3 1
    2 4
    1 4
    Output示例
    Yes
    Yes
    Yes
    No
    No
    Analysis
    第一次知道原来边双联通分量的求法和强联通分量求法几乎一样...
    只不过在无向图中的边双就没有 “在栈中” 的概念了,而是要保证不会走到自己父亲那里
    = = 模拟一下发现确实两种要求的tarjan代码是一模一样的
    = =
     
    Code
     1 #include<stdio.h>
     2 #include<iostream>
     3 #define maxn 1000000
     4 using namespace std;
     5 
     6 int dfn[maxn],low[maxn],TIM,COL,color[maxn],n,m,q;
     7 bool iscut[2*maxn],buck[maxn*2];
     8 
     9 struct edge{ int from,u,v,bri; }e[maxn*2];
    10 int tot,first[maxn]; void insert(int u,int v){
    11     tot++; e[tot].bri = 0; e[tot].u = u; e[tot].from = first[u]; e[tot].v = v; first[u] = tot;
    12 }
    13 
    14 void dfs(int u,int fa){ // To tag the bri
    15     dfn[u] = low[u] = ++TIM;
    16     int child = 0;
    17     for(int i = first[u];i;i = e[i].from){
    18         int v = e[i].v; //if(v == fa) continue;
    19         if(v != fa) child++;
    20         if(!dfn[v]){
    21             dfs(v,u);
    22             low[u] = min(low[u],low[v]);
    23             if(low[v] >= dfn[u]) iscut[u] = true;
    24         }else if(dfn[v] < dfn[u] && v != fa) low[u] = min(low[u],dfn[v]);
    25     }if(fa == u && child > 1) iscut[u] = false;
    26 //    printf("#%d: child %d iscut %d
    ",u,child,iscut[u]);
    27 }
    28 
    29 void tagg(){
    30     for(int i = 1;i <= tot;i++)
    31         if(iscut[e[i].u] && iscut[e[i].v])
    32             e[i].bri = 1, buck[i] = true;
    33 }
    34 
    35 void dfs1(int u,int fa){
    36     color[u] = COL;
    37     for(int i = first[u];i;i = e[i].from){
    38         if(e[i].v == fa || buck[i] || color[e[i].v]) continue;
    39         dfs1(e[i].v,u);
    40     }
    41 }
    42 
    43 int main(){
    44 //    freopen("16.txt","r",stdin);
    45 //    freopen("16.out","w",stdout);
    46     
    47     scanf("%d%d",&n,&m);
    48     
    49     for(int i = 1;i <= m;i++){
    50         int u,v; scanf("%d%d",&u,&v);
    51         insert(u,v); insert(v,u);
    52     }for(int i=1;i<=n;i++)if(!dfn[i])
    53     dfs(i,i); for(int i = 1;i <= n;i++)
    54         if(!e[first[i]].from) iscut[i] = true;
    55 //    for(int i = 1;i <= n;i++) printf("%d ",iscut[i]); cout << endl;
    56     tagg(); 
    57     
    58 //    for(int i = 1;i <= tot;i++) printf("#%d:%d->%d $%d$
    ",i,e[i].u,e[i].v,buck[i]);
    59 //    for(int i = 1;i <= n;i++) printf("%d ",color[i]); cout << endl;
    60     
    61     for(int i = 1;i <= n;i++)
    62         if(!color[i]){ ++COL; dfs1(i,i); }
    63     
    64     scanf("%d",&q);
    65     
    66     for(int i = 1;i <= q;i++){
    67         int u,v; scanf("%d%d",&u,&v);
    68         if(color[u] == color[v]) printf("Yes
    ");
    69         else printf("No
    ");
    70     }
    71     
    72     return 0;
    73 }
    判桥 -> 边双联通
     1 #include<stdio.h>
     2 #include<iostream>
     3 #define maxn 2000000
     4 using namespace std;
     5 
     6 int dfn[maxn],low[maxn],TIM,s[maxn],poi,color[maxn],COL,n,m,q;
     7 
     8 struct edge{ int from, u, v; }e[maxn];
     9 int tot,first[maxn]; void insert(int u,int v){
    10     tot++; e[tot].from = first[u]; e[tot].v = v; e[tot].u = u; first[u] = tot;
    11 }
    12 
    13 void dfs(int u,int fa){
    14 //    printf("Now deep in #%d
    ",u);
    15     dfn[u] = low[u] = ++TIM;
    16     s[poi++] = u;
    17     for(int i = first[u];i;i = e[i].from){
    18         int v = e[i].v; if(!dfn[v]){
    19 //            printf("#%d; get in Poi B
    ",u);
    20             dfs(v,u); low[u] = min(low[u],low[v]);
    21         }else if(dfn[v] < dfn[u] && v != fa) low[u] = min(low[u],dfn[v]);
    22     }//printf("#%d: get in poi A
    ",u);
    23     
    24     if(low[u] == dfn[u]){
    25 //        printf("#%d get the first!
    ",u);
    26         color[u] = ++COL;
    27         while(s[poi-1] != u && poi){
    28             poi--; color[s[poi]] = COL;
    29         }if(poi) poi--;
    30     }
    31 }
    32 
    33 int main(){
    34     scanf("%d%d",&n,&m);
    35     
    36     for(int i = 1;i <= m;i++){
    37         int u,v; scanf("%d%d",&u,&v);
    38         insert(u,v); insert(v,u);
    39     }for(int i = 1;i <= n;i++)
    40         if(!color[i]) dfs(i,i);
    41     
    42 //    for(int i = 1;i <= n;i++) printf("%d ",color[i]); cout << endl;
    43     
    44     scanf("%d",&q);
    45     
    46     for(int i = 1;i <= q;i++){
    47         int u,v; scanf("%d%d",&u,&v);
    48         if(color[u] == color[v]) printf("Yes
    ");
    49         else printf("No
    ");
    50     }
    51     
    52     
    53     
    54     
    55     return 0;
    56 }
    Tarjan强联通分量
  • 相关阅读:
    中芯国际内争的真相
    对Delphi控件作用的新理解(控件本身的源代码就是一个很强的工业级源码)
    百度云怎么赚钱
    百度地图在某架构下找不到符号.a文件的问题
    忽然发现,if语句没有相应的continue功能
    可怜的苏联,以及可恨的戈尔巴乔夫
    感觉镀金没有用,兼论小公司与大公司的选择
    开发团队的民主集中制
    关于明末历史(已全部写完)
    CF 322B Ciel and Flowers 贪心水题
  • 原文地址:https://www.cnblogs.com/Chorolop/p/7804895.html
Copyright © 2011-2022 走看看