LOJ 2979 「THUSCH 2017」换桌——多路增广费用流

题目:https://loj.ac/problem/2979

原来的思路:

  优化连边。一看就是同一个桌子相邻座位之间连边、相邻桌子对应座位之间连边。

  每个座位向它所属的桌子连边。然后每个人建一个点,向若干桌子连边。

  因为连边的桌子是区间,所以线段树优化。

  又想到志愿者招募之类的,所以想弄一个上下界费用流。人向它的座位连下界为1的边,对应桌子区间向人连边。找一些循环流。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define ls Ls[cr]
#define rs Rs[cr]
using namespace std;
int rdn()
{int ret=0;bool fx=1;char ch=getchar();while(ch>'9'||ch<'0'){if(ch=='-')fx=0;ch=getchar();}while(ch>='0'&&ch<='9')ret=ret*10+ch-'0',ch=getchar();return fx?ret:-ret;
}
int Mn(int a,int b){return a<b?a:b;}
const int N=305,M=15,N2=7000,M2=140000,INF=3005;
int n,m,S,T,L[N][M],R[N][M],dy[N],bh[N][M],tot,Ls[N<<1],Rs[N<<1];
int rd[N2],hd[N2],xnt=1,to[M2],nxt[M2],cap[M2],w[M2];
int ans,dis[N2],pr[N2],info[N2]; bool ins[N2];
queue<int> q;
void add(int x,int y,int l,int r,int z)
{rd[y]+=l; rd[x]-=l; ans+=l*z; r-=l;to[++xnt]=y;nxt[xnt]=hd[x];hd[x]=xnt;cap[xnt]=r;w[xnt]=z;to[++xnt]=x;nxt[xnt]=hd[y];hd[y]=xnt;cap[xnt]=0;w[xnt]=-z;
}
void build(int l,int r,int cr)
{if(l==r){dy[l]=cr;return;}int mid=l+r>>1;ls=++tot; build(l,mid,ls);rs=++tot; build(mid+1,r,rs);add(ls,cr,0,INF,0); add(rs,cr,0,INF,0);
}
void qry(int l,int r,int cr,int L,int R,int k)
{if(l>=L&&r<=R){printf("(%d->%d)\n",cr,k);add(cr,k,0,1,0);return;}int mid=l+r>>1;if(L<=mid)qry(l,mid,ls,L,R,k);if(mid<R)qry(mid+1,r,rs,L,R,k);
}
bool spfa()
{memset(dis,0x3f,sizeof dis); info[T]=0;dis[S]=0; info[S]=INF; q.push(S); ins[S]=1;while(q.size()){int k=q.front(); q.pop(); ins[k]=0;for(int i=hd[k],v;i;i=nxt[i])if(cap[i]&&dis[v=to[i]]>dis[k]+w[i]){dis[v]=dis[k]+w[i];pr[v]=i; info[v]=Mn(info[k],cap[i]);if(!ins[v])ins[v]=1,q.push(v);}}return info[T];
}
int ek()
{int tp=info[T];for(int i=pr[T];i;i=pr[to[i^1]]){cap[i]-=tp; cap[i^1]+=tp;ans+=w[i]*tp;printf("%d ",to[i]);}puts("");return tp;
}
int main()
{n=rdn();m=rdn();for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)L[i][j]=rdn()+1;//+1for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)R[i][j]=rdn()+1;tot=1;build(1,n,1); int tmp=n*m;for(int i=1;i<=n;i++,puts(""))for(int j=1;j<=m;j++)bh[i][j]=++tot,printf("%d ",tot);for(int i=1;i<=n;i++)for(int j=1;j<=m;j++){qry(1,n,1,L[i][j],R[i][j],bh[i][j]+tmp);printf("(%d->%d)\n",bh[i][j]+tmp,bh[i][j]);add(bh[i][j]+tmp,bh[i][j],1,1,0);printf("(%d->%d)\n",bh[i][j],dy[i]);add(bh[i][j],dy[i],1,1,0);printf("(%d->%d)[]\n",bh[i][j],bh[i][j==m?1:j+1]);add(bh[i][j],bh[i][j==m?1:j+1],0,INF,1);printf("(%d->%d)[]\n",bh[i][j],bh[i][j>1?j-1:m]);add(bh[i][j],bh[i][j>1?j-1:m],0,INF,1);if(i<n){printf("(%d->%d)[]\n",bh[i][j],bh[i+1][j]);add(bh[i][j],bh[i+1][j],0,INF,2);}}tot+=tmp; S=tot+1; T=tot+2; tmp=0;printf("S=%d T=%d\n",S,T);for(int i=1;i<=tot;i++)if(rd[i]<0)add(i,T,0,-rd[i],0);else if(rd[i]>0)add(S,i,0,rd[i],0),tmp+=rd[i];printf("tmp=%d ans=%d\n",tmp,ans);while(spfa())tmp-=ek();if(tmp)puts("no solution");else printf("%d\n",ans);return 0;
}
View Code

然后发现过不了样例。这样是不行的。希望的是 “因为自己连向 x 座位、 y 桌子向自己连边,所以 x 座位到 y 桌子走了一条路” , 但实际上这样相当于自己给 x 座位一些流量、自己向 y 桌子索求一些流量;如果有另一个人,给 y 桌子某座位一些流量、向 x 座位所在桌子索求流量,那么 x 和 y 之间本应有两条路,现在一条也没有了。

正解和这个类似?

每种座位都建两棵线段树,维护所有桌子,一棵表示向左走,一棵表示向右走;即一共 2*m 棵线段树。

然后每个人向线段树对应节点连边;线段树叶子就表示座位;同一个桌子的座位之间连边即可。

向左走的线段树,从自己到左孩子连的边,费用需要加上 “跨过右孩子” 的代价。即到达向左走的线段树某节点,默认当前在该区间的右端点。所以每个人向区间连的 log 条边要注意一下初始费用。

需要多路增广费用流才能过。多路增广,就是 spfa 一次之后,根据 dis[ cr ] 和 dis[ v ] 的关系,像 dinic 一样走。 dinic 的优化都可以加(似乎一定要加当前弧优化?),注意要像 dfs 一样打 vis 标记,因为 dis 上可能有 0 环。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define ls Ls[cr]
#define rs Rs[cr]
using namespace std;
int rdn()
{int ret=0;bool fx=1;char ch=getchar();while(ch>'9'||ch<'0'){if(ch=='-')fx=0;ch=getchar();}while(ch>='0'&&ch<='9')ret=ret*10+ch-'0',ch=getchar();return fx?ret:-ret;
}
int Mn(int a,int b){return a<b?a:b;}
int Mx(int a,int b){return a>b?a:b;}
const int N=18005,M=276005,INF=3005;
int n,m,S,T,L[305][15],R[305][15],bh[305][15];
int tot,Ls[N],Rs[N],hd[N],xnt=1,to[M],nxt[M],cap[M],w[M];
int ans,mxflow,dis[N],pr[N],info[N]; bool ins[N];
int cur[N];bool vis[N];
queue<int> q;
void add(int x,int y,int c,int z)
{to[++xnt]=y;nxt[xnt]=hd[x];hd[x]=xnt;cap[xnt]=c;w[xnt]=z;to[++xnt]=x;nxt[xnt]=hd[y];hd[y]=xnt;cap[xnt]=0;w[xnt]=-z;
}
void build(int l,int r,int cr,bool fx,int k)
{if(l==r){if(!fx)bh[l][k]=++tot;add(cr,bh[l][k],INF,0); return;}int mid=l+r>>1;ls=++tot; build(l,mid,ls,fx,k);rs=++tot; build(mid+1,r,rs,fx,k);if(fx){ add(cr,ls,INF,0); add(cr,rs,INF,(mid-l+1)*2);}else{ add(cr,ls,INF,(r-mid)*2); add(cr,rs,INF,0);}
}
void qry(int l,int r,int cr,int L,int R,int lj,bool fx)
{if(l>=L&&r<=R){ add(tot,cr,1,lj);return;}int mid=l+r>>1;if(!fx){if(L<=mid)qry(l,mid,ls,L,R,lj+2*(r-mid),fx);if(mid<R)qry(mid+1,r,rs,L,R,lj,fx);}else{if(L<=mid)qry(l,mid,ls,L,R,lj,fx);if(mid<R)qry(mid+1,r,rs,L,R,lj+2*(mid-l+1),fx);}
}
bool spfa()
{memset(dis,0x3f,sizeof dis); info[T]=0;dis[S]=0; info[S]=INF; q.push(S); ins[S]=1;while(q.size()){int k=q.front(); q.pop(); ins[k]=0;for(int i=hd[k],v;i;i=nxt[i])if(cap[i]&&dis[v=to[i]]>dis[k]+w[i]){dis[v]=dis[k]+w[i];pr[v]=i; info[v]=Mn(info[k],cap[i]);if(!ins[v])ins[v]=1,q.push(v);}}return info[T];
}
int dfs(int cr,int flow)
{if(cr==T)return flow;int use=0; vis[cr]=1;for(int &i=cur[cr],v;i;i=nxt[i])if(cap[i]&&!vis[v=to[i]]&&dis[v]==dis[cr]+w[i]){int tmp=dfs(v,Mn(flow-use,cap[i]));if(!tmp)dis[v]=-1;cap[i]-=tmp; cap[i^1]+=tmp; ans+=tmp*w[i];use+=tmp; if(use==flow){vis[cr]=0;return use;}}vis[cr]=0; return use;
}
void solve()
{int tmp;while(spfa()){memcpy(cur,hd,sizeof hd);while(tmp=dfs(S,INF))mxflow+=tmp;}
}
int main()
{n=rdn();m=rdn();for(int i=1;i<=n;i++)for(int j=1;j<=m;j++) L[i][j]=rdn()+1;//+1for(int i=1;i<=n;i++)for(int j=1;j<=m;j++) R[i][j]=rdn()+1;tot=2*m;for(int i=1;i<=m;i++){ build(1,n,i,0,i); build(1,n,i+m,1,i);}for(int i=1;i<=n;i++)for(int j=1;j<=m;j++){ add(bh[i][j],bh[i][j==m?1:j+1],INF,1);add(bh[i][j],bh[i][j==1?m:j-1],INF,1);}for(int i=1;i<=n;i++)for(int j=1;j<=m;j++){tot++;if(L[i][j]<i)qry(1,n,j,L[i][j],Mn(i-1,R[i][j]),-2*(n-i),0);if(R[i][j]>=i)qry(1,n,j+m,Mx(L[i][j],i),R[i][j],-2*(i-1),1);}S=tot+1; T=tot+2;for(int i=tot-n*m+1;i<=tot;i++)add(S,i,1,0);for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)add(bh[i][j],T,1,0);solve();if(mxflow<n*m)puts("no solution");else printf("%d\n",ans);return 0;
}

 

转载于:https://www.cnblogs.com/Narh/p/10841141.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/411492.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java如何实现红包雨,一个简单的红包雨实现

效果图如下&#xff1a;我的视频 1_20170207191503.gif这个简单动画的主要思路&#xff1a; 将多个 红包View 通过 属性动画 从屏幕顶端 飘落到 屏幕底部。只不过在飘落的动画过程中&#xff0c;加入了一些随机路线 Path。主要涉及到的知识点&#xff1a;1.Path 和 PathMeasure…

【原】基于Windows Media Player, 写自己的播放器【有源码,可下载整个工程】

最近有客户问我&#xff0c;怎么把Windows Media Player 嵌套在自己的项目中。 以前我在Delphi下玩过Windows Media Player&#xff0c;可是在Microsoft Visual Studio 2008 没有测试过。 到网上搜索了一把&#xff0c;果然得到很多例子。 其中CSDN上有个例子写的不错&#xff…

Oracle数据库php短连接,PHP 连接 Oracle

起因由于项目的数据库需要用客户购买的Oracle数据库&#xff0c;所以需要php安装oci扩展。运行环境php : 7.2系统: windows10oracle: 11gR2安装相关环境由于php的oci8扩展还是需要使用到oracle的一些包&#xff0c;所以先下载这一些。下载完成后解压缩这个压缩包&#xff0c;并…

计算机考研文章精选[转载]

今天在网上看到了一篇超全的计算机考研文章集合&#xff0c;里面有很多曾经看过&#xff0c;挺经典的&#xff0c;于是忍不住收藏下来&#xff0c;希望对那些即将报考计算机研究生和工作了仍不放弃考研的朋友有所帮助 计算机考研常见问题解答 地址&#xff1a;http://ww…

PHP鼠标滑过变色命令,WordPress鼠标悬停变色的修改方法

原创内容&#xff0c;转载请注明出处&#xff1a;https://www.myzhenai.com.cn/post/3253.html关键词&#xff1a;wordpress 鼠标 悬停 变色我总是觉得我两个WordPress博客的主题里使用的鼠标悬停变色的颜色不太喜欢&#xff0c;就是当鼠标划过或停留在某一个链接上的时候&…

圆面积异常

package zengliang;import java.util.*;public class Suv {public static void main(String[] args) {// TODO 自动生成的方法存根try{double r,s;final double PI 3.14;Scanner scnew Scanner(System.in);System.out.println("输入圆的半径&#xff1a;");r sc.ne…

SpringBoot学习笔记(9)----SpringBoot中使用关系型数据库以及事务处理

在实际的运用开发中&#xff0c;跟数据库之间的交互是必不可少的&#xff0c;SpringBoot也提供了两种跟数据库交互的方式。 1. 使用JdbcTemplate 在SpringBoot中提供了JdbcTemplate模板类&#xff0c;JdbcTemplate提供的方法进行增删改查的操作。 首先需要在pom文件中添加依赖:…

Processes

转载于:https://www.cnblogs.com/EMH899/p/10844709.html

[html] 说说video标签中预加载视频用到的属性是什么?

[html] 说说video标签中预加载视频用到的属性是什么&#xff1f; 个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后端知识。放弃很容易&#xff0c; 但坚持一定很酷。欢迎大家一起讨论 主目录 与歌谣一起通关前端面试题

CodeSmith 5.0工具实例篇系列4——根据表生成修改的存储过程,针对MS Sqlserver

运行该模板时&#xff0c;只需要选择单个表即可。 申明&#xff1a;该系列案例已通过CodeSmith Professional 5.0.1 Revision 4983版本的测试&#xff0c;以及生成的存储过程是针对MS Sqlserver。 操作说明 &#xff1a;运行CodeSmith Studio工具 &#xff0c;创建Blank Templa…

差分放大电路单端输出和双端输出区别以及应用(转载)

来自&#xff1a;http://www.elecfans.com/news/dianzi/20171118581901_a.html 什么是差分放大电路 差分放大电路利用电路参数的对称性和负反馈作用&#xff0c;有效地稳定静态工作点&#xff0c;以放大差模信号抑制共模信号为显著特征&#xff0c;广泛应用于直接耦合电路和测量…

Flash 缓存问题的解决(转)

Flash 缓存问题的解决 作者&#xff1a;wangwaizi 时间&#xff1a; 2003-12-27 文档类型&#xff1a;翻译 来自&#xff1a;蓝色理想 原文是Flash支持中心的两篇文章.解决Flash缓存问题 | 解决载入变量缓存问题 使用以下的方法&#xff0c;使SWF文件强制不从浏览器读本地…

matlab可以使用词云分析吗,利用豆瓣短评数据生成词云

在之前的文章中&#xff0c;我们获得了豆瓣爬取的短评内容&#xff0c;汇总到了一个文件中&#xff0c;但是&#xff0c;没有被利用起来的数据是没有意义的。前文提到&#xff0c;有一篇微信推文的关于词云制作的一个实践记录&#xff0c;准备照此试验一下。思路分析读文件利用…

第一阶段冲刺08

1、整个项目的预期任务量&#xff08;任务量所有工作的预期时间&#xff09;和目前已经花的时间&#xff08;所有记录的‘已经花费的时间’&#xff09;&#xff0c;还剩余的时间&#xff08;所有工作的‘剩余时间’&#xff09;。第一阶段工作预期任务&#xff1a;完成整个App…

matlab中腐蚀图像的编写,Matlab实现二值图像的腐蚀算法源代码

标签&#xff1a;1、二值图像的腐蚀原理&#xff1a;我们知道&#xff0c;二值图像就是0和1组成的矩阵&#xff0c;0为黑1为白&#xff0c;腐蚀作用在1上面也就是图像高光白色部分&#xff0c;然后白色部分往外收缩。腐蚀就是类似于黑色军队反攻白色军队&#xff0c;最终把自己…

第五次实训作业继承

1、实现如下类之间的继承关系&#xff0c;并编写Music类来测试这些类。 2、编写一个Java应用程序&#xff0c;该程序包括3个类&#xff1a;Monkey类、People类和主类E。要求&#xff1a; (1) Monkey类中有个构造方法&#xff1a;Monkey (String s)&#xff0c;并且有个public v…

Chrome 过滤广告插件暂替办法

由于Chrome暂无广告过滤插件&#xff0c;我们只能通过其他方法是实现Google Chrome的广告过滤。 这里我们需要用到Privoxy这款软件&#xff01;由于Privoxy是通过本地代理来实现广告过滤的&#xff0c;所以用chrome也通过Privoxy实现广告过滤。 Privoxy是款免费软件&#xff0c…

JavaScript调用WebServices

经过几天研究&#xff0c;终于可以再单个js文件(纯JavaScript&#xff0c;不涉及AJax控件)调用WebServices了。现将调用方法及注意事项分享给大家 1、WebServices文件源码WebService.asmx usingSystem;usingSystem.Collections;usingSystem.Linq;usingSystem.Web;usingSystem.W…

oracle11g和12c安装区别,Oracle下载与Oracle安装图解(Oracle19c,Oracle18c,Oracle12c,Oracle11g)...

oracle下载与oracle安装图解(oracle19c,oracle18c,oracle12c,oracle11g)1、oracle下载(oracle11g)oracle下载方法&#xff0c;请根据以下步骤与图示来下载oracle11g版本&#xff1a;oracle11g下载第1步&#xff1a;打开oracle官方网站oracle11g下载第2步&#xff1a;打开菜单-支…

nodejs+supertest+mocha 接口测试环境搭建

系统接口自动化测试 该框架用于对系统的接口自动化测试&#xff08;nodejssupertestmocha&#xff09;Homebrew 安装&#xff1a; ruby -e "$(curl -fsSL {}https://raw.githubusercontent.com/Homebrew/install/master/install)" 安装nodejs&#xff1a;brew instal…