zoukankan      html  css  js  c++  java
  • lightoj 1300 边双联通分量+交叉染色求奇圈

    题目链接:http://lightoj.com/volume_showproblem.php?problem=1300

    边双连通分量首先dfs找出桥并标记,然后dfs交叉着色找奇圈上的点。这题只要求在奇圈上的点个数。容易得到,一个边双联通分量如果存在奇圈,那么整个分量上的点都属于某个奇圈。

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<iostream>
    #include<algorithm>
    #include<queue>
    #include<vector>
    using namespace std;
    const int maxn = 11150;
    const int maxe = 30100;
    const int INF = 0x3f3f3f;
    
    int pre[maxn],low[maxn],dfs_clock;
    bool isbridge[maxe*2];
    
    struct Edge{
        int u,v;
        int next;
        Edge(int u=0,int v=0,int next=0): u(u) , v(v), next(next) {}
    }edges[maxe*2];
    int head[maxn],cnt;
    
    int color[maxn];   //用交叉染色法进行判断奇圈;
    bool flag;
    int n,m;
    int ans,tempans;
    
    void tarjan(int u,int fa){
        pre[u] = low[u]  =  dfs_clock++;
        for(int i=head[u];i!=-1;i=edges[i].next){
            int v = edges[i].v;
            if(!pre[v]){
                tarjan(v,u);
                low[u] = min(low[u],low[v]);
                if(low[v] > pre[u])  { isbridge[i] = true;  isbridge[i^1] = true; }
            }
            else if(pre[v] < pre[u] && v != fa)   //u->v是反向边;
                low[u] = min(low[u],pre[v]);
        }
    }
    
    void dfs_paint(int u,int fa_c){
        color[u] = fa_c;
        tempans++;
        for(int i=head[u];i!=-1;i=edges[i].next){
            if(isbridge[i])     continue;       //访问到桥跳过;
            int v = edges[i].v;
            if(!color[v])       dfs_paint(v,3-fa_c);   //还没有染色;
            else if(color[u] == color[v])
                flag = true;
        }
    }
    
    void addedge(int u,int v){
        edges[cnt] = Edge(u,v,head[u]);
        head[u] = cnt++;
    }
    int main()
    {
       // freopen("E:\acm\input.txt","r",stdin);
        int T;
        cin>>T;
        for(int t=1;t<=T;t++){
            cin>>n>>m;
            memset(head,-1,sizeof(head));
            cnt = 0;
            for(int i=1;i<=m;i++){
                int a,b;
                scanf("%d %d",&a,&b);
                edges[cnt] = Edge(a,b,head[a]);
                head[a] = cnt++;
                edges[cnt] = Edge(b,a,head[b]);
                head[b] = cnt++;
                //addedge(a,b);
                //addedge(b,a);
            }
            dfs_clock = 1;
            memset(pre,0,sizeof(pre));
            memset(isbridge,0,sizeof(isbridge));
            for(int i=0;i<n;i++)
                if(!pre[i])    tarjan(i,-1);
    
            memset(color,0,sizeof(color));
            ans = 0;
            for(int i=0;i<n;i++){
                if(!color[i]){
                    flag = false;
                    tempans = 0;
                    dfs_paint(i,1);      //交叉染色法
                    if(flag)
                        ans += tempans;
                }
            }
            printf("Case %d: %d
    ",t,ans);
        }
    }
    View Code
  • 相关阅读:
    多线程与Socket编程
    正则表达式
    委托事件泛型
    C#基础加强
    随笔
    不设置JAVA_HOME运行eclipse
    CentOS7.x系统中使用Docker时,在存储方面需要注意的问题
    【转】关于高可用负载均衡的探索-基于Rancher和Traefic
    Rancher 容器管理平台-免费视频培训-链接及内容-第三季
    使用Rancher的RKE快速部署Kubernetes集群
  • 原文地址:https://www.cnblogs.com/acmdeweilai/p/3266324.html
Copyright © 2011-2022 走看看