$BZOJ3232$ 圈地游戏 网络流
正解:最小割+01分数规划
解题报告:
感$jio$这个好像是$NOIp2018$集训的时候$cjk$学长讲01分数规划的时候港的,,,?$QwQ$虽然我还是不会嘤
首先看到这个分数形式,又说是最大值,显然考虑01分数规划呗?然后就考虑怎么$check$?
先更新下每条边的权值变成了$ed_{val}\cdot mid$,然后现在就要算$\sum ed_{val}-\sum nod_{val}$
然后再考虑下什么样的边会被计入?就如果一条边的一边格子被选了另一边没被选就会被计入答案嘛$QwQ$
这时候就会$jio$得有点儿像最小割辣,,,?就是减法,然后又有一定的彼此之间滴制约关系啥的
然后我开始想到这儿就$jio$得,黑白染色然后黑色建一排白色建一排相邻格子之间连边然后就做完辣$QwQ$?
仔细一想发现布星,因为这样并不能保证只围出了一个圈,,,不能作出约束$QwQ$
于是考虑再换一种建边方式?发现上面的问题在于没有对不能选的点作出约束,所以显然所有点要放一排$QwQ$
欧克这样显然可以满足关于点的需求了,但是依然要考虑关于边的条件$QwQ$
考虑相邻格子之间连流量为边权的双向边,保证如果两个点中如果相邻俩格子一个选了一个没选就必须把这条边的边权也割了$QwQ$
然后还有就所有边界上的点都要和$T$连一条流量为边界边权的边,这个挺显然?因为如果选了这个点一定是要付出边权的代价的鸭$QwQ$
然后就跑个最小割就成$QwQ$
如果实在无法理解建图的可以自己画下图,,,说实话这个建图方法我也麻油想到,我看了题解之后自己画了个图才$get$的,,,$QwQ$
$over$
最后我一定要感谢这道题,,,它让我意识到我滴二分+网络流一定有问题,,,(我连$T$三道二分+网络流就是找不到错我还以为是我常数太大嘤,,,
港下问题在哪儿$QwQ$?就,$bfs,dfs,dinic$中判断$\neq 0$改成判断$>eps$,$over$
// luogu-judger-enable-o2
#include<bits/stdc++.h>
using namespace std;
#define lf double
#define il inline
#define gc getchar()
#define t(i) edge[i].to
#define w(i) edge[i].wei
#define n(i) edge[i].nxt
#define ri register int
#define rb register int
#define rc register char
#define rp(i,x,y) for(int i=x;i<=y;++i)
#define my(i,x,y) for(int i=x;i>=y;--i)
#define e(i,x) for(int i=head[x];~i;i=n(i)) const int N=1e4+,M=;
const lf eps=1e-,inf=1e9;
int n,m,dep[N],head[N],cur[N],S,T,ed_cnt=-,val[M][M],h[M][M],s[M][M];
lf l,r=,sum;
struct ed{int to,nxt;lf wei;}edge[N<<]; il int read()
{
rc ch=gc;ri x=;rb y=;
while(ch!='-' && (ch>'' || ch<''))ch=gc;
if(ch=='-')ch=gc,y=;
while(ch>='' && ch<='')x=(x<<)+(x<<)+(ch^''),ch=gc;
return y?x:-x;
}
il int nam(ri x,ri y){return (x-)*m+y;}
il void ad(ri x,ri y,lf z)
{
//printf("%d -> %d : %.3lf\n",y,x,z);
edge[++ed_cnt]=(ed){x,head[y],z};head[y]=ed_cnt;edge[++ed_cnt]=(ed){y,head[x],};head[x]=ed_cnt;}
il bool bfs()
{
queue<int>Q;Q.push(S);memset(dep,,sizeof(dep));dep[S]=;
while(!Q.empty())
{ri nw=Q.front();Q.pop();e(i,nw)if(w(i)>eps && !dep[t(i)]){dep[t(i)]=dep[nw]+,Q.push(t(i));if(t(i)==T)return ;}}
return ;
}
lf dfs(ri nw,lf flow)
{
if(nw==T || flow<eps)return flow;lf ret=;
for(ri &i=cur[nw];~i;i=n(i))
if(w(i)>eps && dep[t(i)]==dep[nw]+)
{lf tmp=dfs(t(i),min(flow,w(i)));ret+=tmp,w(i)-=tmp;w(i^)+=tmp,flow-=tmp;}
if(ret<eps)dep[nw]=;
return ret;
}
il lf dinic(){lf ret=;while(bfs()){rp(i,S,T)cur[i]=head[i];while(){lf d=dfs(S,inf);ret+=d;if(d<=eps)break;}}return ret;}
il bool check(lf mid)
{
memset(head,-,sizeof(head));ed_cnt=-;
rp(i,,n)rp(j,,m)ad(nam(i,j),S,val[i][j]);
rp(i,,n-)rp(j,,m)ad(nam(i+,j),nam(i,j),mid*h[i][j]),ad(nam(i,j),nam(i+,j),mid*h[i][j]);
rp(i,,n)rp(j,,m-)ad(nam(i,j),nam(i,j+),mid*s[i][j]),ad(nam(i,j+),nam(i,j),mid*s[i][j]);
rp(i,,m)ad(T,nam(,i),mid*h[][i]),ad(T,nam(n,i),mid*h[n][i]);//,printf("QwQ mid=%lf h=%d h=%d\n",mid,h[0][i],h[n][i]);
rp(i,,n)ad(T,nam(i,),mid*s[i][]),ad(T,nam(i,m),mid*s[i][m]);//,printf("QwQQ mid=%lf s=%d s=%d\n",mid,s[i][0],s[i][m]);
lf tmp=dinic();
//printf("mid=%.3lf sum=%lf dinic()=%.3lf\n",mid,sum,tmp);
return abs(sum-tmp)>eps;
} int main()
{
//freopen("3232.in","r",stdin);freopen("3232.out","w",stdout);
n=read();m=read();S=;T=n*m+;
rp(i,,n)rp(j,,m)sum+=(val[i][j]=read());rp(i,,n)rp(j,,m)h[i][j]=read();rp(i,,n)rp(j,,m)s[i][j]=read();
while(r-l>eps){lf mid=(l+r)/;if(check(mid))l=mid;else r=mid;}
printf("%.3lf\n",r);
return ;
}
随机推荐
- Flask学习之九 分页
英文博客地址:http://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-ix-pagination 中文翻译地址:http:// ...
- Python基础:20类的定制
类中有一些可自定义的特殊方法,它们中的一些有预定义的默认行为,而其它一些则没有,留到需要的时候去实现.这些特殊方法是Python中用来扩充类的强有力的方式.它们可以实现模拟标准类型和重载操作符等.比如 ...
- A.The beautiful values of the palace 南京网络赛
A对于知道了解主席树性质的人来说,的确算是一个模板题目 题目在于给一个螺旋矩阵,以及一些权值,问在二维区间内权值和是多少? 对于螺旋矩阵权值来说,计算每个点的值,只需要O1计算即可.我们可以通过计算内 ...
- php解压缩
1.zip文件 2.rar文件 3.php调用linux指令进行解压缩 解压7z文件: 注:Windows下的文件编码和LINUX不一样,中文系统为GB,LINUX为UTF-8编码,这种情况下,中文名 ...
- gensim的word2vec如何得出词向量(python)
首先需要具备gensim包,然后需要一个语料库用来训练,这里用到的是skip-gram或CBOW方法,具体细节可以去查查相关资料,这两种方法大致上就是把意思相近的词映射到词空间中相近的位置. 语料库t ...
- 2013-4-3 C#中alt键不是Keys.Alt 而是 Keys.LMenu
2013-4-3 C#中alt键不是Keys.Alt而是Keys.LMenu
- pip安装软件包报Could not fetch URL
报这个错误的原因是python.org已经不支持TLSv1.0和TLSv1.1了.更新pip可以解决这个问题,但是你不能用命令 pip install --upgrade pip 做更新,因为TLS证 ...
- iptablesIP规则的保存与恢复
iptables-save把规则保存到文件中,再由目录rc.d下的脚本(/etc/rc.d/init.d/iptables)自动装载 使用命令iptables-save来保存规则.一般用 iptabl ...
- HDU 1271
这题做了好久..... 理解别人的代码都理解了好久!!!太弱太弱. #include<iostream> #include<algorithm> #include<cma ...
- Python--day41--守护线程
1,守护线程:守护线程会在主线程结束之后等待其他子线程的结束才结束 拓展--守护进程:守护进程随着主进程代码的执行结束而结束 代码示例:守护线程.py import time from threadi ...