• [agc006f] Blackout 神题


    Description

    ​ 给你一个NN行NN列的网格,第ii行第jj列的格子用(i,j)(i,j)表示
    一开始的时候有MM个格子被涂成黑色,其他的格子都是白色,具体一点,涂成黑色的格子为(a1,b1),(a2,b2),(a3,b3)...(aM,bM)(a1,b1),(a2,b2),(a3,b3)...(aM,bM)
    你的目标是按照以下规则将尽可能多的白色格子涂成黑色:如果存在三个格子(x,y)(x,y),(y,z)(y,z)和(z,x)(z,x)满足(x,y)(x,y)和(y,z)(y,z)都是黑格子并且(z,x)(z,x)是白格子(其中x,y,zx,y,z都是[1,N][1,N]之间的整数),那么你可以将(z,x)(z,x)涂成黑色
    输出你不能继续操作时,黑格子的最大数量

    Input

    ​ 第一行两个正整数N,MN,M
    接下来MM行每行两个正整数(ai,bi)(ai,bi)表示一开始被涂成黑色的格子

    Output

    ​ 共一行,一个整数ansans表示不能操作时黑格子的最大数量

    Sample Input

    #Sample1
    3 2
    1 2
    2 3
    
    #Sample2
    2 2
    1 1
    1 2
    
    #Sample3
    4 3
    1 2
    1 3
    4 4
    

    Sample Output

    #Sample1
    3
    
    #Sample2
    4
    
    #Sample3
    3
    

    HINT

    数据范围:

    ​ 对于100%的数据,1<=N,M<=105,1<=ai,bi<=N1<=N,M<=105,1<=ai,bi<=N,并且所有的(ai,bi)(ai,bi)互不相同

    样例解释:

    ​ Sample1:(1,2)(1,2)和(2,3)(2,3)都是黑的,可将白格(3,1)(3,1)涂成白色

    ​ Sample2:(1,1)(1,1)和(1,2)(1,2)都是黑的,可将白格(2,1)(2,1)涂成黑色;接着(2,1)(2,1)和(1,2)(1,2)都是黑的,可将白格(2,2)(2,2)涂成黑色

    ​ Sample3:无法操作

    Sol

    对于每个黑色点,我们直接连边x-y,然后发现距离为3的点可以产生贡献的边。

    为了处理这个问题,我们对图进行012染色,x-y连距离1,y-x连距离2,根据距离mod3决定染得颜色,之后0-1,1-2,2-0都是合法的变黑的方案。。。答案为(c0*c1+c1*c2+c2*c0)

    假设染色出现环,画个图就知道所有点都能互相连边,所以答案是(size^2)

    如果根本染不满,就是原来的数量。。。

    其实上面讲的不是核心思想。。。核心思想之有第一句,后面的只是一种高效简洁的实现方法。。。

    Code

    #include <bits/stdc++.h>
    using namespace std;
    int n,m,x,y,col[100005],cnt[5],ok;long long ans;vector<pair<int,int> >e[100005];
    void dfs(int x)
    {
        cnt[col[x]]++;
        for(int i=0;i<e[x].size();i++)
        {
            if(e[x][i].second==1) cnt[3]++;
            if(col[e[x][i].first]==-1) col[e[x][i].first]=(col[x]+e[x][i].second)%3,dfs(e[x][i].first);
            else if((col[x]+e[x][i].second)%3!=col[e[x][i].first]) ok=1;
        }
    }
    int main()
    {
        scanf("%d%d",&n,&m);memset(col,-1,sizeof(col));
        for(int i=1;i<=m;i++) scanf("%d%d",&x,&y),e[x].push_back(make_pair(y,1)),e[y].push_back(make_pair(x,2));
        for(int i=1;i<=n;i++) if(col[i]==-1)
        {
            memset(cnt,0,sizeof(cnt));ok=col[i]=0;dfs(i);
            if(ok){ans+=1ll*(cnt[0]+cnt[1]+cnt[2])*(cnt[0]+cnt[1]+cnt[2]);continue;}
            else if((!cnt[0])||(!cnt[1])||(!cnt[2])){ans+=1ll*cnt[3];continue;}
            else ans+=1ll*cnt[0]*cnt[1]+1ll*cnt[1]*cnt[2]+1ll*cnt[2]*cnt[0];
        }
        printf("%lld
    ",ans);
    }
    
    
  • 相关阅读:
    Jenkins配置钉钉通知
    Jenkins 学习笔记
    2020年10月26日Britain suggests it may overturn parts of the EU withdrawal agreement
    【火爆抢答中】HarmonyOS有奖问答,更多惊喜等你来拿!
    三七互娱《斗罗大陆:魂师对决》上线,Network Kit助力玩家即刻畅玩
    运动健康南向设备接入服务传输数据解析举例
    华为商品管理系统批量更新商品时提示:请至少输入一组国家码和价格
    云空间服务,助力用户数据存储与协同
    Input组件无点击效果
    华为视频编辑服务(Video Editor Kit),助力开发者高效构建应用视频编辑能力
  • 原文地址:https://www.cnblogs.com/CK6100LGEV2/p/9520652.html
Copyright © 2020-2023  润新知