zoukankan      html  css  js  c++  java
  • bzoj4238: 电压

    删除这条边后,图是一个二分图

    那么这条边一定要在所有奇环上,并且不在偶环上。

    把dfs树搞出来,遇到环就把整个环分奇偶情况标记

    标记树上的一段路径可以树上差分一下

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    const int inf=(1<<30)-1;
    
    struct node
    {
        int x,y,next;
    }a[410000];int len,last[110000];
    int ec[410000],ef[410000];
    int pc[110000],pf[110000];
    void ins(int x,int y)
    {
        len++;
        a[len].x=x;a[len].y=y;
        a[len].next=last[x];last[x]=len;
    }
    int z,cnt,dfn[110000],dep[110000],fr[110000];
    void dfs(int x)
    {
        dfn[x]=++z;
        for(int k=last[x];k;k=a[k].next)
        {
            int y=a[k].y;
            if(dfn[y]==0)
            {
                dep[y]=dep[x]+1;
                fr[y]=k;
                dfs(y);
            }
        }
        
        for(int k=last[x];k;k=a[k].next)
        {
            int y=a[k].y;
            if(dfn[y]>dfn[x]&&fr[y]!=k)
            {
                int e=dep[y]-dep[x]+1;
                if(e&1)ec[k>>1]++,pc[y]++,pc[x]--,cnt++;
                else   ef[k>>1]++,pf[y]++,pf[x]--;
            }
        }
    }
    void dfs2(int x)
    {
        dfn[x]=++z;
        for(int k=last[x];k;k=a[k].next)
        {
            int y=a[k].y;
            if(dfn[y]==0)
            {
                dfs2(y);
                pc[x]+=pc[y];
                pf[x]+=pf[y];
            }
        }
        if(dfn[x]!=1)
        {
            ec[fr[x]>>1]+=pc[x];
            ef[fr[x]>>1]+=pf[x];
        }    
    }
    
    int tp,list[110000];
    int main()
    {
        freopen("a.in","r",stdin);
        freopen("a.out","w",stdout);
        int n,m,x,y;
        scanf("%d%d",&n,&m);
        len=1;memset(last,0,sizeof(last));
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d",&x,&y);
            ins(x,y),ins(y,x);
        }
        z=cnt=tp=0;
        for(int i=1;i<=n;i++)
            if(dfn[i]==0)fr[i]=0,dep[i]=0,dfs(i);
        z=0;
        memset(dfn,0,sizeof(dfn));
        for(int i=1;i<=n;i++)
            if(dfn[i]==0)dfs2(i);
            
        int ans=0;
        for(int i=1;i<=m;i++)
            if(ec[i]==cnt&&ef[i]==0)ans++;
        printf("%d
    ",ans);
        
        return 0;
    }
  • 相关阅读:
    Android_AyscnTask
    Android_handler
    Android_网络操作
    Android_网络基础
    Android_Fragment
    Android_activity 生命周期
    Android-Dialog
    android_menu
    Android-约束布局
    andorid_相对布局小练习
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/10223355.html
Copyright © 2011-2022 走看看