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);
    }
    
  • 相关阅读:
    Python基础
    XML文件的基础使用
    正则表达式的基本使用
    hafs的java_api(转载)
    HDFS常用的Shell命令(转载)
    安装hadoop2.4.1
    配置JDK环境变量
    准备Linux环境
    Winform窗体屏蔽Alt+F4强制关闭
    leetcode 0214
  • 原文地址:https://www.cnblogs.com/cjoierShiina-Mashiro/p/12463634.html
Copyright © 2011-2022 走看看