首页 > 其他分享 >P3756 [CQOI2017] 老C的方块

P3756 [CQOI2017] 老C的方块

时间:2024-04-02 20:22:24浏览次数:24  
标签:val int 类点 dep MAXN P3756 CQOI2017 include 方块

原题链接

感觉挺有意思的。

先简化一下不合法的状况,实际上是如果特殊边两侧都有点,且那两个点的另外三个联通方向上也有至少一个点,就是坏的。相当于是四个限制只要有一个不满足就可以了。于是就可以转化成最小割。

按四种限制将点分成四类。特殊边两侧分别是 \(1\) 类点和 \(2\) 类点,\(1\) 类点四联通的非 \(2\) 类点是 \(3\) 类点,\(2\) 类点四联通的非 \(1\) 类点是 \(4\) 类点。如下图所示。

这样标号以后,我们就可以通过在不同编号的点中连边来做到从源点分别经过四条限制到达汇点。一个周期中的点就长这样:

至于删掉每个格子的代价,\(3\) 类点可以在源点到它的边上将容量设为其权值,表示删掉 \(3\) 类点,\(3\) 类点到 \(1\) 类点的边上设为 INF 表示不能删。\(4\) 类点同理。

当然我们是可以删掉 \(1\) 类点和 \(2\) 类点的,只需要在 \(1\) 类点到 \(2\) 类点的边上将权值设为它俩权值中较小值即可。

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/hash_policy.hpp>
#include<queue>
using namespace std;
using namespace __gnu_pbds;
const int MAXN=1e5+10,MAXM=4e5+10,INF=1e9+7;
int C,R,n,s,t,x[MAXN],y[MAXN],w[MAXN],dep[MAXN],ans;
int to[MAXM],nxt[MAXM],head[MAXN],cur[MAXN],val[MAXM],cnt=1;
gp_hash_table <int,int> p[MAXN];
inline void add(int x,int y,int v)
{
    to[++cnt]=y,nxt[cnt]=head[x];
    head[x]=cnt,val[cnt]=v;return ;
}
inline void edd(int x,int y,int v){add(x,y,v),add(y,x,0);}
inline bool bfs()
{
    for(int i=s;i<=t;++i) dep[i]=-1,cur[i]=head[i];
    dep[s]=0;queue <int> q;q.push(s);
    while(!q.empty())
    {
        int x=q.front();q.pop();
        for(int i=head[x];i;i=nxt[i])
        {
            int y=to[i];
            if(val[i]&&dep[y]==-1)  
                dep[y]=dep[x]+1,q.push(y);
        }
    }
    return dep[t]!=-1;
}
int dfs(int x,int flow)
{
    if(x==t) return flow;int rmn=flow;
    for(int i=cur[x];i&&rmn;i=nxt[i])
    {
        int y=to[i];if(!val[i]||dep[y]!=dep[x]+1) continue;
        int f=dfs(y,min(rmn,val[i]));
        rmn-=f,val[i]-=f,val[i^1]+=f;
    }
    return flow-rmn;
}
int main()
{
#ifdef ONLINE_JUDGE
    cin.tie(0),cout.tie(0);
    ios::sync_with_stdio(0);
#else
    freopen("in.in","r",stdin);
    freopen("out.out","w",stdout);
#endif
    cin>>C>>R>>n;s=0,t=n+1;
    for(int i=1;i<=n;++i)
    {
        cin>>x[i]>>y[i]>>w[i];
        p[x[i]][y[i]]=i;
    }
    for(int i=1;i<=n;++i)
    {
        int k=(x[i]&3)^(y[i]&1),j;//这里是用位运算确定是哪一类点。
        if(!k)
        {
            if((y[i]&1)&&(j=p[x[i]+1][y[i]])) edd(i,j,min(w[i],w[j]));
            if(!(y[i]&1)&&(j=p[x[i]-1][y[i]])) edd(i,j,min(w[i],w[j]));
        }
        if(k==3)
        {
            if((y[i]&1)&&(j=p[x[i]+1][y[i]])) edd(i,j,INF);
            if(!(y[i]&1)&&(j=p[x[i]-1][y[i]])) edd(i,j,INF);
            if(j=p[x[i]][y[i]+1]) edd(i,j,INF);
            if(j=p[x[i]][y[i]-1]) edd(i,j,INF);
        }
        if(k==1)
        {
            edd(s,i,w[i]);
            if((y[i]&1)&&(j=p[x[i]+1][y[i]])) edd(i,j,INF);
            if(!(y[i]&1)&&(j=p[x[i]-1][y[i]])) edd(i,j,INF);
            if(j=p[x[i]][y[i]+1]) edd(i,j,INF);
            if(j=p[x[i]][y[i]-1]) edd(i,j,INF);
        }
        if(k==2) edd(i,t,w[i]);
    }
    while(bfs()) ans+=dfs(s,INF);
    cout<<ans<<'\n';return 0;
}

标签:val,int,类点,dep,MAXN,P3756,CQOI2017,include,方块
From: https://www.cnblogs.com/int-R/p/18111432/P3756

相关文章

  • love 2d Lua 俄罗斯方块超详细教程
    源码已经更新在CSDN的码库里:gitclonehttps://gitcode.com/funsion/love2d-game.git一直在找Lua能快速便捷实现图形界面的软件,找了一堆,终于发现love2d是小而美的原生lua图形界面实现的方式。并参考相关教程做了一个更详细的,以便入门。功能如上图,开发过程用了love2d,......
  • Java练手游戏--俄罗斯方块
    Java基础小练手游戏项目:俄罗斯方块简单版使用Java实现俄罗斯方块大概思路:界面设计:使用JavaSwing或JavaFX创建游戏窗口和用户界面。创建一个主窗口类(如GameFrame.java),负责设置窗口大小、标题等属性。设计游戏面板(如GamePanel.java),用于绘制游戏区域、下一个方块预览区、得......
  • P2135 方块消除
    原题链接题解代码量小的离谱,思维难度大的离谱对于两个原本不相邻的同色区域块,历经千辛万苦碰面的场景,我们可以描述成右边的区域块为左边的区域块消除的时候增添了长度设\(dp[i][j][suf]\)代表消除区域\([i,j]\)同时该区域的\(j\)增添了长度\(suf\)但是合并消除不一定......
  • 方块掉落
    方块掉落题目描述最近阿宁对一个名叫“方块掉落”的游戏感兴趣,沉迷于此。每局游戏一开始,有一条无限长的水平线、一个箭头、一个操作序列$t$,没有任何方块。操作序列$t$是一个字符串,仅包含"YBR"三种字符,分别代表颜色黄蓝红。依次按照操作序列$s$掉落不同颜色的方块。如果......
  • 2024牛客寒假算法基础集训营4 K.方块掉落
    线段树维护的信息有当前行有多少方块,一共有多少方块拿线段树维护一个矩阵就行,转移更新就是矩阵乘类似题有这个 牛客多校第二场-H-zhujio两题都基本上就是转移矩阵求出来正常建线段树,pushup就是直接矩阵乘 #include<bits/stdc++.h>usingnamespacestd;#defineen......
  • Umov移动方块-scratch编程作品
    程序说明:《Umov移动方块》是一款基于Scratch平台制作的小游戏。在这个游戏中,玩家将面对一个3×3的圆圈棋盘,并通过鼠标控制蓝色方块在这些圆圈中灵活移动。游戏的挑战在于,舞台的四周边缘会不断生成白色小球,它们会向对向移动。玩家的目标是尽量让蓝色方块避免与这些移动的小球发生......
  • C#版俄罗斯方块
    C#版俄罗斯方块 C++是游戏编程的首选语言,但我相信C++能做到的C#也能做到。本篇介绍用C#编写一个俄罗斯方块程序的原理,以及在C#里面播放声音,保存游戏设置的方法。游戏界面预览:菜单预览:自定义每个小方块颜色功能界面:游戏主要有四部分组成:Square类,Block类,gameField类,游戏引擎Square类:......
  • 俄罗斯方块诞生30周年:作者回顾创作过程
    俄罗斯方块诞生30周年:作者回顾创作过程投递人 itwriter 发布于 2014-06-0618:20 评论(0) 有445人阅读 原文链接 [收藏] « »导语:今天,是俄罗斯方块诞生30周年,“俄罗斯方块之父”阿列克谢·帕基特诺夫(AlexeyPajitnov)撰文,对这款经典游戏的诞生过程进行了简单......
  • 美国13岁少年通关原版俄罗斯方块:历史首人,此前仅AI可完成
    美国13岁少年通关原版俄罗斯方块:历史首人,此前仅AI可完成投递人 itwriter 发布于 2024-01-0417:00 评论(0) 有233人阅读 原文链接 [收藏] « »俄罗斯方块这款经典游戏想必大家都玩过,但能将其通关的人此前从未出现。近日,这一空白终于被打破。美国一名13岁......
  • 在 Excel 里研发俄罗斯方块;全国首例「AI 声音侵权案」审理丨 RTE 开发者日报 Vol.106
       开发者朋友们大家好: 这里是「RTE开发者日报」,每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享RTE(RealTimeEngagement)领域内「有话题的新闻」、「有态度的观点」、「有意思的数据」、「有思考的文章」、「有看点的会议」,但内容仅代表......