https://www.luogu.org/problemnew/show/U18202

暴力搜索预期得分3030分左右。

状压预期得分7070分左右。

考虑费用流,将剩余不稳定度和最小转为消除不稳定度和最大。

首先拐角处只能放在有不稳定度的格子上:如果它的拐角处放在了X+YX+Y为偶数的格子上,那么它不仅没有减少不稳定度,而且还占地。这个贪心显然正确。

那么黑白染色,X+YX+Y为偶数的点分一类,为奇数的分一类。将LL形柱子抽象成两个非拐角处的格子的路径(这两个格子的X+YX+Y都为偶数,拐角处的第三个格子的X+YX+Y为奇数)。那么这两个格子肯定一个在奇数列一个在偶数列,证明显然。

于是建图:

  • 一共有四列点。

  • X+Y为偶数的点再分为两类:奇数列的和偶数列的。

  • 奇数列的点放在左边(第一列),源点向每个点连一条容量为1,费用为0的边。

  • 偶数列的点放在右边(第四列),每个点向汇点连一条容量为1,费用为0的边。

  • X+Y为奇数的点每个点拆开,一分为二,分别放在第二列和第三列。第二列的每个点向第三列的自己连一条容量为1,费用为负的该点的权值(不稳定度)。

  • 如果第一列(X+Y为偶数,奇数列的点)和第二列的点相邻,连一条容量为1,费用为0的边,第三、四列同理。

  • 当然塌了的格子不能连边。

跑一遍最小费用最大流即可。这样建图每次增广的流都肯定为11,所以可以在最大流为MM的时候直接跳出。期望得分4040分。

(???)

因为这样是错的,

4 4 6
0 1 0 1000
0 0 0 0
0 1 0 1
0 0 0 0
1 1
2 1
2 3
4 1
4 3
4 4

就是一个构造的反例。我们不能先保证总流量最大再保证总费用最小,而是要尽可能地让总费用最小。也就是说我们要把柱子用在刀刃上,而不是放越多越好。于是想到如果本次增广源点到汇点的费用为正,直接跳出即可。(我的构造方式是连负费用边,如果连正权边跑最长路那么费用为负跳出即可)

彩蛋:

额,我不太会构造这样的数据,就把这一小片乘以1000贴在后面每个数据的左上角了。所以这么写也可以AC:printf("%d\n",sum+mincost-998000);

额我在说什么...

这样就可以100100分,复杂度O(O(费用流))。

题解:https://www.luogu.org/blog/zhoutb2333/dong-xue-yu-xian-ti-xie

暴力:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <string>
#include <ctime>
#include <cstdlib> using namespace std;
const int N = ; #define yxy getchar()
#define R freopen("gg.in", "r", stdin) bool vis[N][N];
int w[N][N];
int n, m, k, Answer, All; inline int read(){
int x = ; char c = yxy;
while(c < '' || c > '') c = yxy;
while(c >= '' && c <= '') x = x * + c - '', c = yxy;
return x;
} void dfs(int step, int cut, int I, int J){
if(cut > Answer) Answer = cut;
if(step == m + ) return;
for(int i = ; i <= n; i ++) {
for(int j = ; j <= n; j ++){
if(i < I && j < J) continue ;
if(!vis[i][j] && w[i][j]){ //以当前点为拐点,每个点处枚举四种状态
int x, y, x_, y_;
x = i, y = j - , x_ = i - , y_ = j;
if(y > && x_ > && !vis[x][y] && !vis[x_][y_]) { //朝向左上
vis[i][j] = ; vis[x][y] = ; vis[x_][y_] = ;
cut += w[i][j];
dfs(step + , cut, i, j);
cut -= w[i][j];
vis[i][j] = ; vis[x][y] = ; vis[x_][y_] = ;
}
x = i + , y = j, x_ = i, y_ = j + ;
if(x <= n && y_ <= n && !vis[x][y] && !vis[x_][y_]) { //朝向右下
vis[i][j] = ; vis[x][y] = ; vis[x_][y_] = ;
cut += w[i][j];
dfs(step + , cut, i, j);
cut -= w[i][j];
vis[i][j] = ; vis[x][y] = ; vis[x_][y_] = ;
}
x = i, y = j - , x_ = i + , y_ = j;
if(y > && x_ <= n && !vis[x][y] && !vis[x_][y_]) { // 左下
vis[i][j] = ; vis[x][y] = ; vis[x_][y_] = ;
cut += w[i][j];
dfs(step + , cut, i, j);
cut -= w[i][j];
vis[i][j] = ; vis[x][y] = ; vis[x_][y_] = ;
}
x = i - , y = j, x_ = i, y_ = j + ;
if(x > && y_ <= n && !vis[x][y] && !vis[x_][y_]) { // 右上
vis[i][j] = ; vis[x][y] = ; vis[x_][y_] = ;
cut += w[i][j];
dfs(step + , cut, i, j);
cut -= w[i][j];
vis[i][j] = ; vis[x][y] = ; vis[x_][y_] = ;
}
}
}
}
} int main()
{
n = read(); m = read(); k = read();
for(int i = ; i <= n; i ++)
for(int j = ; j <= n; j ++){
int W = read();
w[i][j] = W, All += w[i][j];
} for(int i = ; i <= k; i ++){
int x = read(), y = read();
vis[x][y] = ; //标记为1的已经塌陷
}
dfs(, , , );
printf("%d", All - Answer);
return ;
}

正解

#include<bits/stdc++.h>
#define maxn 105
#define maxe 100010
#define INF 1<<30
using namespace std; int head[maxe],nxt[maxe],point[maxe],flow[maxe],val[maxe],tot=;
int pre[maxe],preedge[maxe],tmpflow[maxe],dis[maxe],s=,t=,E,ofs=;
int v[maxn][maxn],sum,n,m,k;
bool in[maxe];
queue<int> q;
int get(int x,int y,int lvl){
return (x-)*n+y+ofs*lvl;
}
bool chk(int num){
num%=ofs;
int x=(num-)/n+,y=(num-)%n+;
if(x<||y<||x>n||y>n||v[x][y]==-)
return false;
return true;
}
void ADD(int x,int y,int f,int c){
val[++tot]=c;
flow[tot]=f;
point[tot]=y;
nxt[tot]=head[x];
head[x]=tot;
}
void add(int x,int y,int f,int c){
if((x!=s&&x!=t&&!chk(x))||(y!=s&&y!=t&&!chk(y)))
return;
ADD(x,y,f,c),ADD(y,x,,-c);
}
bool bfs(){
memset(dis,0x3f,sizeof(dis));
dis[s]=,in[s]=true,q.push(s),tmpflow[s]=m;
while(!q.empty()){
int x=q.front();
in[x]=false;
q.pop();
for(int j=head[x];j;j=nxt[j]){
if(!flow[j]||dis[point[j]]<=dis[x]+val[j])
continue;
dis[point[j]]=dis[x]+val[j];
pre[point[j]]=x;
preedge[point[j]]=j;
tmpflow[point[j]]=min(tmpflow[x],flow[j]);
if(!in[point[j]])
in[point[j]]=true,q.push(point[j]);
}
}
return dis[t]!=0x3f3f3f3f;
}
int main(){
int x,y,mincost=;
scanf("%d%d%d",&n,&m,&k);
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
scanf("%d",&v[i][j]),sum+=v[i][j];
for(int i=;i<=k;i++)
scanf("%d%d",&x,&y),v[x][y]=-;
for(int i=;i<=n;i++)
for(int j=;j<=n;j++){
if((i+j)%)
add(get(i,j,),get(i,j,),,-v[i][j]);
else{
if(j%){
add(s,get(i,j,),,);
add(get(i,j,),get(i,j-,),,);
add(get(i,j,),get(i,j+,),,);
add(get(i,j,),get(i-,j,),,);
add(get(i,j,),get(i+,j,),,);
}
else{
add(get(i,j,),t,,);
add(get(i,j-,),get(i,j,),,);
add(get(i,j+,),get(i,j,),,);
add(get(i-,j,),get(i,j,),,);
add(get(i+,j,),get(i,j,),,);
}
}
}
while(bfs()&&m){
if(dis[t]>)
break;
int k=t;
while(k!=s){
flow[preedge[k]]-=tmpflow[t];
flow[preedge[k]^]+=tmpflow[t];
k=pre[k];
}
m-=tmpflow[t];
mincost+=dis[t]*tmpflow[t];
}
printf("%d\n",sum+mincost);
return ;
}

[Luogu] U18202 洞穴遇险的更多相关文章

  1. 【刷题】洛谷 P4142 洞穴遇险

    题目背景 ZRQ在洞穴中准备采集矿物的时候遇险了!洞穴要塌了! 题目来源:zhoutb2333 题目描述 整个洞穴是一个 \(N*N\) 的方格图,每个格子形如 \((X,Y),1 \le X,Y \ ...

  2. Luogu 2147 洞穴勘测 - LCT

    Solution $LCT$ 打上 $cut$ , $link$ 和 $finroot$ 即可 Code #include<cstdio> #include<cstring> ...

  3. [luoguP4142]洞穴遇险

    https://www.zybuluo.com/ysner/note/1240792 题面 戳我 解析 这种用来拼接的奇形怪状的东西,要不就是轮廓线\(DP\),要不就是网络流. 为了表示奇数点(即\ ...

  4. 二分图&网络流初步

    链接 : 最小割&网络流应用 EK太低级了,不用. 那么请看:#6068. 「2017 山东一轮集训 Day4」棋盘,不用EK你试试? dinic模板及部分变形应用见zzz大佬的博客:网络流学 ...

  5. 【题解】Luogu P2147 [SDOI2008]洞穴勘测

    原题传送门 这题用Link-Cut-Tree解决,Link-Cut-Tree详解 我不太会踩爆Link-Cut-Tree的并查集做法qaq 我们用Link-Cut-Tree维护连通性(十分无脑) Co ...

  6. 洛谷P2147 [SDOI2008] 洞穴勘探 [LCT]

    题目传送门 洞穴勘探 题目描述 辉辉热衷于洞穴勘测. 某天,他按照地图来到了一片被标记为JSZX的洞穴群地区.经过初步勘测,辉辉发现这片区域由n个洞穴(分别编号为1到n)以及若干通道组成,并且每条通道 ...

  7. BZOJ2049:[SDOI2008]洞穴勘测——题解

    http://www.lydsy.com/JudgeOnline/problem.php?id=2049 https://www.luogu.org/problemnew/show/P2147 辉辉热 ...

  8. [luogu P1776] 宝物筛选 解题报告(单调队列优化DP)

    题目链接: https://www.luogu.org/problemnew/show/P1776 题目: 终于,破解了千年的难题.小FF找到了王室的宝物室,里面堆满了无数价值连城的宝物……这下小FF ...

  9. Luogu 魔法学院杯-第二弹(萌新的第一法blog)

    虽然有点久远  还是放一下吧. 传送门:https://www.luogu.org/contest/show?tid=754 第一题  沉迷游戏,伤感情 #include <queue> ...

随机推荐

  1. SAS学习笔记26 方差分析

    对于多于两组(k>2)样本均数的比较,t检验不再适用,方差分析(analysis of variance, ANOVA)则是解决上述问题的重要分析方法.方差分析由R.A.Fisher(1923) ...

  2. 关于OI中的各种数学

    学到后面数学越来越多了,感觉好难啊,开个博客专门记录一下数学相关的东西 因为反正也没人看,所以主要还是给自己看的 一些符号: 数论函数的卷积:$\ast$,$ h = f \ast g$ 则 $h(n ...

  3. Nomogram(诺莫图) | Logistic、Cox生存分析结果可视化

    本文首发于“生信补给站”公众号,https://mp.weixin.qq.com/s/BWpy3F-nEKXCdVXmY3GYZg 当然还有更多R语言,生物信息学相关知识...

  4. 写给Web开发人员看的Nginx介绍

    译者注:不知道其他开发者是否和我一样,参与或者写了很多Web项目,但是却没有真正的去完整的部署应用,很多时候都是交给ops即运维的同学帮忙来做.而作为一个有节操的开发者,我认为了解一些服务器方面的知识 ...

  5. ORACLE:锁被未决分布式事务处理 18.27.160617 持有

    1. 以管理员账号登陆 2. rollback  force '18.27.160617 ';

  6. C#强制回收垃圾

    [DllImport("psapi.dll")] private static extern int EmptyWorkingSet(int hProcess); public v ...

  7. \lib\cmsis\stm32f10x.h(298): error: #67: expected a "}"

    首先介绍一下csdn屏蔽广告 这个至关重要,请参考 https://blog.csdn.net/qq_40881680/article/details/82226562 更新KEIL5以后,原KEIL ...

  8. The openssl extension is missing, which means that secure HTTPS transfers are impossible

    执行命令:curl -sS https://getcomposer.org/installer | php报错如下Some settings on your machine make Composer ...

  9. Image Processing and Analysis_15_Image Registration:Multi-modal volume registration by maximization of mutual information——1996

    此主要讨论图像处理与分析.虽然计算机视觉部分的有些内容比如特 征提取等也可以归结到图像分析中来,但鉴于它们与计算机视觉的紧密联系,以 及它们的出处,没有把它们纳入到图像处理与分析中来.同样,这里面也有 ...

  10. HRNet网络结构

    最近正在阅读CVPR2019的论文Deep High-Resolution Representation Learning for Human Pose Estimation. 无奈看论文中的Netw ...