zoukankan      html  css  js  c++  java
  • 【题解】【BZOJ】AGC008F Blackout

    AGC006F Blackout

    AGC006F Blackout

    1 题外话

    什么神仙题目

    2 sol

    对黑格子((x,y)) ,连一条(x->y) 的边

    此时问题变为如果存在(x->y,y->z) 的边,那么添加一条(z->x) 的边,最后统计总共有多少条边

    现在我们只考虑每个弱连通块怎么统计

    尝试对每一个弱连通块三色染色

    2.1 无法染色

    此时的图中一定有二元环/自环

    经过一次操作后二元环能构造出自环,而自环能在若干次操作后将当前弱联通块变为完全图

    2.2 不完全染色(用不到第二种或第三种颜色)

    此时图中不会出现新边

    2.3 染色成功

    此时连通块的边数为(1->2、2->3、3->1) 的边数总和

    3 code

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define int long long
    using namespace std;
    
    const int N=100010;
    const int M=100010;
    
    inline void read(int &x) {
        x=0;
        int f=1;
        char ch=getchar();
        while(ch<'0'||ch>'9') {
            if (ch=='-') {
                f=-1;
            }
            ch=getchar();
        }
        while(ch>='0'&&ch<='9') {
            x=x*10+ch-'0';
            ch=getchar();
        }
        x*=f;
    }
    
    struct note {
        int t;
        int next;
        int val;
    };
    
    int cnt;
    int head[N];
    note e[M<<1];
    
    inline void add(int x,int y,int val) {
        e[++cnt].t=y;
        e[cnt].next=head[x];
        e[cnt].val=val;
        head[x]=cnt;
    }
    
    int n,m;
    int vis[N];
    
    int f[3],siz;
    int edg;
    bool lab;
    
    void dfs(int p,int v) {
        vis[p]=v;
        f[v]++;
        siz++;
        for(int i=head[p];i+1;i=e[i].next) {
            int t=e[i].t;
            if (e[i].val==1) {
                edg++;
            }
            if (vis[t]==-1) {
                dfs(t,(v+e[i].val)%3);
            } else if (vis[t]!=(vis[p]+e[i].val)%3) {
                lab=0;
            }
        }
    }
    
    int ans;
    
    signed main() {
        read(n),read(m);
        memset(head,-1,sizeof(head));
        for(int i=1;i<=m;i++) {
            int x,y;
            read(x),read(y);
            add(x,y,1);
            add(y,x,2);
        }
        memset(vis,-1,sizeof(vis));
        for(int i=1;i<=n;i++) {
            if (vis[i]==-1) {
                lab=1;
                f[0]=f[1]=f[2]=0;
                siz=edg=0;
                dfs(i,0);
                if (lab) {
                    if (min(f[0],min(f[1],f[2]))==0) {
                        ans+=edg;
                    } else {
                        ans+=f[0]*f[1]+f[1]*f[2]+f[2]*f[0];
                    }
                } else {
                    ans+=siz*siz;
                }
            }
        }
        printf("%lld
    ",ans);
        return 0;
    }
    

    4 注意

    打得挺长(

    Author: tt66ea

    Created: 2021-09-01 周三 20:50

    Validate

  • 相关阅读:
    28、列举常见的内置函数(各个函数的示例,一大半没写全,慢慢更新,会全的)
    Django之前端插件定制之表头
    26、Python的可变类型和不可变类型?
    25、Python垃圾回收机制?
    24、简述Python的深浅拷贝以及应用场景
    基础题(五)
    使用OpenCV和Python进行人脸识别
    Codeforces Round #253 (Div. 2)B(暴力枚举)
    uva11609(组合数学,快速幂)
    uva10892(暴力枚举)
  • 原文地址:https://www.cnblogs.com/tt66ea-blog/p/15216383.html
Copyright © 2011-2022 走看看