zoukankan      html  css  js  c++  java
  • AGC006F Blackout

    Link
    先转化模型:给定一个有向图,若图中存在((u,v),(v,w)),那么可以连((u,w)),求最后有多少边。
    那么我们现在先把每个弱连通块分开讨论,显然不同弱连通块之间是互不影响的。
    把这个连通块三染色((R ightarrow G ightarrow B)),如果无法染色,那么这个弱连通块会变成一个完全图。
    如果只用了不到三种颜色,那么肯定无法继续操作。
    如果成功三染色,那么所有(R ightarrow B,G ightarrow R,B ightarrow G)都会连上。
    用并查集染色即可。

    #include<cstdio>
    #include<numeric>
    using i64=long long;
    const int N=300007;
    int a[N],b[N],f[N],g[N],fa[N],s[N],t[N],vis[N];
    int read(){int x;scanf("%d",&x);return x;}
    int find(int x){return x==fa[x]? x:fa[x]=find(fa[x]);}
    void merge(int x,int y){fa[find(x)]=find(y);}
    int main()
    {
        int n=read(),m=read();i64 ans=0;std::iota(fa+1,fa+n*3+1,1);
        for(int i=1;i<=m;++i) ++f[a[i]=read()],++g[b[i]=read()],merge(a[i],b[i]+n),merge(a[i]+n,b[i]+n+n),merge(a[i]+n+n,b[i]);
        for(int i=1;i<=n;++i) if(++s[find(i)],++t[find(i+n)],f[i]&&g[i]) vis[find(i)]=vis[find(i+n)]=vis[find(i+n+n)]=1;
        for(int i=1;i<=n*3;++i) if(find(i)==i&&vis[i]) ans+=1ll*s[i]*t[i];
        for(int i=1;i<=m;++i) ans+=!vis[find(a[i])];
        printf("%lld
    ",ans);
    }
    
  • 相关阅读:
    无有和无穷
    算法设计 熄灯问题
    WPF 路由事件总结
    C# params关键字
    WPF 布局总结
    C#结构体和类的区别
    C#装箱和拆箱(值类型和引用类型之间的转换)
    OpenGL中平移、旋转、缩放矩阵堆栈操作
    OpenGL图元的颜色属性
    OpenGL基础图形的绘制
  • 原文地址:https://www.cnblogs.com/cjoierShiina-Mashiro/p/12463634.html
Copyright © 2011-2022 走看看