NKOJ 4042 (CQOI 2017) 老C的方块(最小割+染色)
来源:互联网 发布:淘宝上亚马逊会员代买 编辑:程序博客网 时间:2024/05/19 04:27
P4042老C的方块
问题描述
此题比较明显可以想到图论,由于是经典的棋盘问题,我们观察四种讨厌的形状,发现这四种形状有一个共同特点,即都可以看成以特殊边为邻边的两个方块各自再连上一个方块,然后我们发现,特殊边的分布刚好是配合这个规律的,于是我们将棋盘染色
染色很丑陋,因为是我故意的。
简单说一下,我们将格子分成4类,分别是四种颜色,我们发现,如果一个图形是讨厌的,那么一定满足这个图形是黄-黑-白-蓝,或者黄-白-黑-蓝,于是构图的方法也就出来了
我们新建一个源点S,和一个汇点T。
从S出发连到黄色格子,容量是他的费用。
从黄色格子连到他所相邻的黑色和白色格子,容量无穷大。
相邻黑白格子之间连双向边,容量是黑白格子中费用较小的一个。
从黑白格子出发,连到相邻的蓝色格子,容量无穷大。
从蓝色格子出发,连到汇点T。
最后求出上图的最小割即可。
附上代码:
#include<stdio.h>#include<iostream>#include<algorithm>#include<cstring>#include<map>#define ll long long#define N 4234567using namespace std;struct node{ll xi,yi,wi,id;};const ll ct=1000000LL;ll S,T,C,R,n;map<ll,node>Q;node P[N];ll TOT=1,NE[N],EN[N],G[N],LA[N],dis[N],cnt[N];void ADD(ll x,ll y,ll z){ TOT++; EN[TOT]=y; G[TOT]=z; NE[TOT]=LA[x]; LA[x]=TOT;}void A1(ll k){ ll t;node tmp; ADD(S,k,P[k].wi);ADD(k,S,0); t=P[k].xi*ct+ct+P[k].yi; if(Q.count(t)) { tmp=Q[t]; ADD(k,tmp.id,1e18); ADD(tmp.id,k,0); } t-=2*ct; if(Q.count(t)) { tmp=Q[t]; ADD(k,tmp.id,1e18); ADD(tmp.id,k,0); } if(P[k].xi&1) { t=P[k].xi*ct+P[k].yi+1; if(Q.count(t)) { tmp=Q[t]; ADD(k,tmp.id,1e18); ADD(tmp.id,k,0); } } else { t=P[k].xi*ct+P[k].yi-1; if(Q.count(t)) { tmp=Q[t]; ADD(k,tmp.id,1e18); ADD(tmp.id,k,0); } }}void A2(ll k){ ll t;node tmp; t=P[k].xi*ct+P[k].yi+1; if(Q.count(t)) { tmp=Q[t]; ADD(k,tmp.id,min(P[k].wi,tmp.wi)); ADD(tmp.id,k,0); ADD(tmp.id,k,min(P[k].wi,tmp.wi)); ADD(k,tmp.id,0); }}void A3(ll k){ ll t;node tmp; ADD(k,T,P[k].wi);ADD(T,k,0); t=P[k].xi*ct+ct+P[k].yi; if(Q.count(t)) { tmp=Q[t]; ADD(tmp.id,k,1e18); ADD(k,tmp.id,0); } t-=2*ct; if(Q.count(t)) { tmp=Q[t]; ADD(tmp.id,k,1e18); ADD(k,tmp.id,0); } if(!(P[k].xi&1)) { t=P[k].xi*ct+P[k].yi+1; if(Q.count(t)) { tmp=Q[t]; ADD(tmp.id,k,1e18); ADD(k,tmp.id,0); } } else { t=P[k].xi*ct+P[k].yi-1; if(Q.count(t)) { tmp=Q[t]; ADD(tmp.id,k,1e18); ADD(k,tmp.id,0); } }}ll tp(ll x,ll y){ ll p=y&3; if(x&1)return p+1; if(p==0)return 3; if(p==1)return 1; if(p==2)return 4; if(p==3)return 2;}void edge(){ ll i,t; for(i=1;i<=n;i++) { t=tp(P[i].xi,P[i].yi); if(t==1)A1(i); if(t==2)A2(i); if(t==4)A3(i); }}ll SAP(ll u,ll f){ ll i,v,d=0,tmp; if(u==T)return f; for(i=LA[u];i>1;i=NE[i]) { v=EN[i]; if(G[i]&&dis[u]==dis[v]+1) { tmp=SAP(v,min(f-d,G[i])); G[i]-=tmp; G[i^1]+=tmp; d+=tmp; if(f==d||dis[S]>=n+2)return d; } } if(!--cnt[dis[u]])dis[S]=n+2; cnt[++dis[u]]++; return d;}int main(){ ll i,x,y,w,ans=0;node tmp; scanf("%lld%lld%lld",&C,&R,&n); for(i=1;i<=n;i++) { scanf("%lld%lld%lld",&y,&x,&w); tmp.id=i;tmp.wi=w; P[i].xi=x;P[i].yi=y;P[i].wi=w;P[i].id=i; Q[x*ct+y]=tmp; } S=n+1;T=S+1;edge(); while(dis[S]<n+2)ans+=SAP(S,1e18); cout<<ans;}
阅读全文
0 0
- NKOJ 4042 (CQOI 2017) 老C的方块(最小割+染色)
- NKOJ 3611(CQOI 2016) 不同的最小割(分治+最小割=最小割树)
- BZOJ 4823: [Cqoi2017]老C的方块(最小割)
- NKOJ 4043 (CQOI 2017) 老C的键盘 (树形DP)
- [最小割] BZOJ 4823 [Cqoi2017]老C的方块
- NKOJ 4038(CQOI 2017) 小Q的棋盘(贪心)
- 【CQOI 2016】不同的最小割
- 【CQOI2017】老C的方块
- 【CQOI2017】bzoj4823 老C的方块
- 4823: [Cqoi2017]老C的方块
- 【BZOJ4823】 [Cqoi2017]老C的方块
- NKOJ 3540 方块游戏(dp)
- NKOJ 4040 (CQOI 2017) 小Q的表格(莫比乌斯反演+分块+递推+线性筛/欧拉函数+分块+线性筛)
- bzoj4823 cqoi2017 老C的方块【最大流】
- NKOJ 3252 (CQOI 2015) 多项式(数学,高精度)
- NKOJ 3253 (CQOI 2015) 标识设计(状压DP)
- NKOJ 3615(CQOI 2016) 路由表(trie)
- NKOJ 3614(CQOI 2016) 密钥破解(Pollard Rho)
- 操作文件和目录
- php-cgi php-fpm说明
- 英文禁止溢出/ios自带美化去除/ios兼容go(-1)问题
- ZOJ
- Windows命令行查看文件的MD5 和win10下获取md5-sha1
- NKOJ 4042 (CQOI 2017) 老C的方块(最小割+染色)
- 数据库概念
- android沉浸式状态栏封装—教你玩出新花样
- px dip sp
- Java 初级
- 监控工具之cacti
- 【js基础】Dom实现换肤效果
- Struts2
- Linux系统编程:标准IO和文件IO的区别