• loj 1300( 边双联通 + 判奇圈 )


    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=27010

    思路:首先Tarjan标记桥,然后对于dfs遍历整个图,我们可以得出一个简单的结论,就是如果一个双连通分量中存在奇圈,那么这个双连通分量中的所有点都可行,于是我们可以dfs染色判奇圈。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 #define MAXN 22222
     7 
     8 struct Edge{
     9     int v,next;
    10 }edge[MAXN<<1];
    11 
    12 int n,m,NE;
    13 int head[MAXN];
    14 
    15 void Insert(int u,int v)
    16 {
    17     edge[NE].v=v;
    18     edge[NE].next=head[u];
    19     head[u]=NE++;
    20 }
    21 
    22 int low[MAXN],dfn[MAXN],cnt;
    23 bool bridge[MAXN<<1];
    24 bool mark[MAXN];
    25 
    26 void Tarjan(int u,int father)
    27 {
    28     low[u]=dfn[u]=++cnt;
    29     mark[u]=true;
    30     for(int i=head[u];i!=-1;i=edge[i].next){
    31         int v=edge[i].v;
    32         if(v==father)continue;
    33         if(dfn[v]==0){
    34             Tarjan(v,u);
    35             low[u]=min(low[u],low[v]);
    36             if(low[v]>dfn[u]){
    37                 bridge[i]=bridge[i^1]=true;
    38             }
    39         }else if(mark[v]){
    40             low[u]=min(low[u],dfn[v]);
    41         }
    42     }
    43 }
    44 
    45 int flag,ans;
    46 int color[MAXN];
    47 
    48 void dfs(int u,int state)
    49 {
    50     cnt++;
    51     color[u]=state;
    52     for(int i=head[u];i!=-1;i=edge[i].next){
    53         int v=edge[i].v;
    54         if(bridge[i])continue;
    55         if(color[v]&&color[u]==color[v]){
    56             flag=1;
    57         }else if(color[v]==0){
    58             dfs(v,3-state);
    59         }
    60     }
    61 }
    62 
    63 int main()
    64 {
    65     int _case,u,v,t=1;
    66      scanf("%d",&_case);
    67     while(_case--){
    68         scanf("%d%d",&n,&m);
    69         NE=0;
    70         memset(head,-1,sizeof(head));
    71         while(m--){
    72             scanf("%d%d",&u,&v);
    73             Insert(u,v);
    74             Insert(v,u);
    75         }
    76         cnt=0;
    77         memset(mark,false,sizeof(mark));
    78         memset(dfn,0,sizeof(dfn));
    79         memset(bridge,false,sizeof(bridge));
    80         for(int i=0;i<n;i++)if(dfn[i]==0)Tarjan(i,i);
    81         memset(color,0,sizeof(color));
    82         ans=0;
    83         for(int i=0;i<n;i++){
    84             if(color[i]==0){
    85                 flag=0;
    86                 cnt=0;
    87                 dfs(i,1);
    88                 if(flag)ans+=cnt;
    89             }
    90         }
    91         printf("Case %d: %d
    ",t++,ans);
    92     }
    93     return 0;
    94 }
    95 
    96 
    97 
    98         
    View Code
  • 相关阅读:
    0127 date dateformat calebdar
    0126 字符串缓冲区StringBuffer类 正则表达式
    0126 String类
    0125 java API object
    0125 匿名对象 内部类 包 代码块
    0123 final关键字,static 关键字
    0123 this关键字 super关键字
    0122面向对象 构造方法
    0122面向对象3 多态
    0120 面向对象2
  • 原文地址:https://www.cnblogs.com/wally/p/3338311.html
Copyright © 2020-2023  润新知