【题解】CQOI2017老C的方块
网络流真的是一种神奇的算法。在一张图上面求感觉高度自动化的方案一般而言好像都是网络流的主阵地。讲真一开始看到这道题也有点懵,题面很长,感觉很难的样子。不过,仔细阅读了题意之后明白了:我们所要做的就是要用最小的代价,使得最后的图中不能出现给定的四种图案。
实际上之前做过一道非常毒瘤的网络流题目【无限之环】。当时就思考了一下:为什么出题人规定不能旋转直线管子?原因就是因为这样的图建不出来,它与不具有其他的管子的特点。那么可以断定:给出的这四个图案必然也是非常特殊的图形,否则不会只有这四个/不会是这四个。于是观察这四个图案,不难发现它们的特征:以一对中间夹了特殊边的方块为中心,分别有另一方块随意连接在上方。
我们从这个中心开始入手:由于要求最小值,所以-->最小割 / 费用流。但一个直观的感觉,它是在很多的方案当中做出选择,与最小割是比较贴合的。(每一种图案牵扯到四个方块,拿掉任何一个就可以破坏这个图形)如果每一种方案彼此平行,只需建出图暴力跑即可。可是会有交叉:当我们删去一个方块时,可能同时破坏了两个方案。
观察图案,由于上下,左右交错,一个中心只可能出现在一个方案中,但其两侧的方块却可能出现在不同的方案当中。于是我们对于这样两侧的方块进行黑白染色,保证每一种方案当中所牵涉到的另两个方块分别属于不同的颜色(由于题目的特殊性质是可以做到的)。
那么建边的方式也十分的自然了:
源点-->所有白色的点,边权为代价;所有白色的点-->中心连边,边权为INF;所有的中心 = 两条边 = 边权为各个方块的代价。所有的中心 --> 黑点,黑点 --> 汇点,边权为代价。此时的最小割所代表的意义即为我们做出的最小代价方案选择。
做出这题还是比较开心的,代码跑得也很快。不过细节比较多,要注意一下……
// luogu-judger-enable-o2
#include <bits/stdc++.h>
using namespace std;
#define maxn 300000
#define maxm 800000
#define ll long long
#define INF 9999999
int C, R, n, S, T, tot;
int Color[maxn], cnt;
int cnp = , head[maxn], cur[maxn];
int lev[maxn];
map <int, int> Map;
int dx[] = {, , , , , , -, -, -, -};
int dy[] = {-, , , , -, , -, , , }; struct edge
{
int to, last, f;
}E[maxm]; struct node
{
int x, y, w;
}P[maxn]; bool cmp(node a, node b)
{
if(a.x != b.x) return a.x < b.x;
return a.y < b.y;
} int read()
{
int x = , k = ;
char c;
c = getchar();
while(c < '' || c > '') { if(c == '-') k = -; c = getchar(); }
while(c >= '' && c <= '') x = x * + c - '', c = getchar();
return x * k;
} void add(int u, int v, int f)
{
E[cnp].to = v, E[cnp].f = f, E[cnp].last = head[u], head[u] = cnp ++;
E[cnp].to = u, E[cnp].f = , E[cnp].last = head[v], head[v] = cnp ++;
} bool Bfs()
{
queue <int> q;
memset(lev, , sizeof(lev));
q.push(S); lev[S] = ;
while(!q.empty())
{
int u = q.front(); q.pop();
for(int i = head[u]; i; i = E[i].last)
{
int v = E[i].to;
if(!lev[v] && E[i].f)
{
lev[v] = lev[u] + ;
q.push(v);
}
}
if(lev[T]) return ;
}
return ;
} int Dfs(int u, int nf)
{
if(u == T) return nf;
int lf = ;
for(int i = cur[u]; i; i = E[i].last)
{
int v = E[i].to;
if(lev[v] == lev[u] + && E[i].f)
{
int af = Dfs(v, min(E[i].f, nf));
nf -= af, lf += af;
E[i].f -= af, E[i ^ ].f += af;
if(!nf) return lf;
cur[u] = i;
}
}
if(!lf) lev[u] = -;
return lf;
} int Dinic()
{
int ans = ;
while(Bfs())
{
memcpy(cur, head, sizeof(head));
ans += Dfs(S, INF);
}
return ans;
} int id(int x, int y)
{
ll k = 1ll * R * (x - ) + 1ll * y;
if(Map[k]) return Map[k];
else return Map[k] = ++ tot;
} int Check(int x, int y)
{
ll k = 1ll * R * (x - ) + 1ll * y;
if(Map[k]) return Map[k];
else return ;
} void Get_Graph(int p)
{
int a = ++ tot, b = ++ tot, c = ++ tot;
add(a, b, P[p].w); add(b, c, P[p + ].w);
for(int i = ; i < ; i ++)
{
int xx = P[p].x + dx[i], yy = P[p].y + dy[i], tem;
if(xx < || xx > C || yy < || yy > R) continue;
if(tem = Check(xx, yy))
{
if(Color[tem] == ) add(tem, a, INF);
else add(c, tem, INF);
}
}
} int main()
{
C = read(), R = read();
swap(C, R); n = read();
S = , T = * n + ;
for(int i = ; i <= n; i ++)
{
int x = read(), y = read(), w = read();
swap(x, y);
if((x & ) && ((!((y - ) % )) || (!((y - ) % ))))
{
P[++ cnt].x = x, P[cnt].y = y;
P[cnt].w = w; continue;
}
if((!(x & )) && ((!((y - ) % )) || (!((y - ) % ))))
{
P[++ cnt].x = x, P[cnt].y = y;
P[cnt].w = w; continue;
}
if(x & )
{
if(((y - ) % )) add(S, id(x, y), w), Color[id(x, y)] = ;
else add(id(x, y), T, w), Color[id(x, y)] = ;
}
else
{
if(!((y - ) % )) add(id(x, y), T, w), Color[id(x, y)] = ;
else add(S, id(x, y), w), Color[id(x, y)] = ;
}
}
sort(P + , P + + cnt, cmp);
for(int i = ; i <= cnt; i += )
{
if(P[i + ].x != P[i].x) continue;
if(P[i + ].y != P[i].y + ) continue;
Get_Graph(i);
}
printf("%d\n", Dinic());
return ;
}
【题解】CQOI2017老C的方块的更多相关文章
- bzoj4823: [Cqoi2017]老C的方块(最小割)
4823: [Cqoi2017]老C的方块 题目:传送门 题解: 毒瘤题ORZ.... 太菜了看出来是最小割啥边都不会建...狂%大佬强强强 黑白染色?不!是四个色一起染,四层图跑最小割... 很 ...
- 【BZOJ4823】[CQOI2017]老C的方块(网络流)
[BZOJ4823][CQOI2017]老C的方块(网络流) 题面 BZOJ 题解 首先还是给棋盘进行黑白染色,然后对于特殊边左右两侧的格子单独拎出来考虑. 为了和其他格子区分,我们把两侧的这两个格子 ...
- bzoj 4823: [Cqoi2017]老C的方块 [最小割]
4823: [Cqoi2017]老C的方块 题意: 鬼畜方块游戏不解释... 有些特殊边,有些四个方块组成的图形,方块有代价,删掉一些方块使得没有图形,最小化代价. 比较明显的最小割,一个图形中必须删 ...
- BZOJ4823 [Cqoi2017]老C的方块 【最小割】
题目 老C是个程序员. 作为一个懒惰的程序员,老C经常在电脑上玩方块游戏消磨时间.游戏被限定在一个由小方格排成的R行C列网格上,如果两个小方格有公共的边,就称它们是相邻的,而且有些相邻的小方格之间的公 ...
- [bzoj4823][洛谷P3756][Cqoi2017]老C的方块
Description 老 C 是个程序员. 作为一个懒惰的程序员,老 C 经常在电脑上玩方块游戏消磨时间.游戏被限定在一个由小方格排成的R行C列网格上 ,如果两个小方格有公共的边,就称它们是相邻的, ...
- [CQOI2017]老C的方块 网络流
---题面--- 题解: 做这题做了好久,,,换了4种建图QAQ 首先我们观察弃疗的形状,可以发现有一个特点,那就是都以一个固定不变的特殊边为中心的,如果我们将特殊边两边的方块分别称为s块和t块, 那 ...
- [bzoj4823][Cqoi2017]老C的方块
来自FallDream的博客,未经允许,请勿转载,谢谢. 挺有意思的一道题.... 看完题面比较明确是最小割,考虑怎么建图 想了比较久 突破口应该是题目中那张奇怪的图 观察这个奇怪的图和方块,很容易发 ...
- [CQOI2017]老C的方块
题目描述 https://www.lydsy.com/JudgeOnline/problem.php?id=4823 题解 观察那四种条件 有没有什么特点? 我们可以把蓝线两边的部分看做两个区域,这样 ...
- bzoj千题计划300:bzoj4823: [Cqoi2017]老C的方块
http://www.lydsy.com/JudgeOnline/problem.php?id=4823 讨厌的形状就是四联通图 且左右各连一个方块 那么破坏所有满足条件的四联通就好了 按上图方式染色 ...
随机推荐
- Flask之endpoint错误View function mapping is overwriting an existing endpoint function: ***
最近在学习Flask, 其中遇到了一个错误, 发现这个问题和Flask, 路由有关系, 所以就记了下来 错误代码: from flask import Flask, render_template, ...
- php file_exists中文路径不存在问题
php的file_exists函数使用中文路径,会显示文件不存在,即使文件已经存在了也会报这个错. 解决方法: <?php $file_name='D://360极速浏览器下载//a.txt'; ...
- 阅读《大型网站技术架构》,并结合"重大需求征集系统"有感
今天阅读了<大型网站技术架构:核心原理与案例分析>的第五.六.七章.这三张主要是讲述了一个系统的可用性.伸缩性和可扩展性.而根据文中所讲述的,一个系统的可用性主要是体现在这个系统的系统服务 ...
- 网站安全检测 漏洞检测 对thinkphp通杀漏洞利用与修复建议
thinkphp在国内来说,很多站长以及平台都在使用这套开源的系统来建站,为什么会这么深受大家的喜欢,第一开源,便捷,高效,生成静态化html,第二框架性的易于开发php架构,很多第三方的插件以及第三 ...
- 一些matlab教程资源收藏,使用matlab编程的人还是挺多的
Matlab教程专题资源免费下载整理合集收藏 <MATLAB从入门到精通>高清文字版[PDF] 103.9MB 简体中文 <矩阵实验室>(Mathworks.Matlab.R2 ...
- Excel学习路径总结
本片涉及从入门到Excel的各个方向,包含众多资料和自己学习的心得,希望您可以仔细阅之: 入门篇: 无论是软件,还是编程,最好的入门就是通过看视频来学习,视频优点为很容易看清楚,手把手教授,不容易 ...
- ActivityStream是什么?什么是Feed流?
我先说说feed流吧,它就是社交网站中用户活动信息流,例如用户写了博客.发了照片.评论了什么等等.Facebook叫newsFeed.推特叫TimeLineFeed.ActivityStream是这些 ...
- BZ 600题祭
不知不觉就600题了呢. 明天就要省选了.不要让这个数字定格在这里吧!
- 1977: [BeiJing2010组队]次小生成树 Tree
1977: [BeiJing2010组队]次小生成树 Tree https://lydsy.com/JudgeOnline/problem.php?id=1977 题意: 求严格次小生成树,即边权和不 ...
- cgi、fastcgi、php-cgi、php-fpm的关系
1. CGI CGI全称是"公共网关接口"(Common Gateway Interface),HTTP服务器与你的或其它机器上的程序进行"交谈"的一种工具,其 ...