思路:这题的原型题是比较经典的网络流。原型题模型就是把所有的障碍去掉。

有障碍做法还是一样的,只用将每个列和行重新划分,求最大流就行了。

#include <cstring>
#include <algorithm>
#include <vector>
#include <cstdio>
#define Maxn 120010
#define Maxm 210000
#define LL int
#define inf 100000000
#define Abs(a) (a)>0?(a):(-a)
using namespace std;
struct Edge{
int from,to,next;
LL val;
}edge[Maxm];
const double eps=1e-;
LL value[Maxn];
int head[Maxn],work[Maxn],dis[Maxn],q[Maxn],e,vi[Maxn];
void init()
{
e=;
memset(head,-,sizeof(head));
}
void add1(int u,int v,LL c)//有向边
{
edge[e].to=v;edge[e].val=c;edge[e].next=head[u];head[u]=e++;
edge[e].to=u;edge[e].val=;edge[e].next=head[v];head[v]=e++;
}
void add2(int u,int v,LL c)//无向边
{
edge[e].to=v;edge[e].val=c;edge[e].next=head[u];head[u]=e++;
edge[e].to=u;edge[e].val=c;edge[e].next=head[v];head[v]=e++;
}
int bfs(int S,int T)
{
int rear=;
memset(dis,-,sizeof(dis));
dis[S]=;q[rear++]=S;
for(int i=;i<rear;i++)
{
for(int j=head[q[i]];j!=-;j=edge[j].next)
{
if(edge[j].val&&dis[edge[j].to]==-)
{
dis[edge[j].to]=dis[q[i]]+;
q[rear++]=edge[j].to;
if(edge[j].to==T) return ;
}
}
}
return ;
}
LL dfs(int cur,LL a,int T)
{
if(cur==T) return a;
for(int &i=work[cur];i!=-;i=edge[i].next)
{
if(edge[i].val&&dis[edge[i].to]==dis[cur]+)
{
LL t=dfs(edge[i].to,min(a,edge[i].val),T);
if(t)
{
edge[i].val-=t;
edge[i^].val+=t;
return t;
}
}
}
return ;
}
LL Dinic(int S,int T)
{
LL ans=;
while(bfs(S,T))
{
memcpy(work,head,sizeof(head));
while(LL t=dfs(S,inf,T)) ans+=t;
}
return ans;
}
int g[][],row,col,beg[][],gg[][];
void build(int n,int m)
{
int i,j,f=;
row=col=;
for(i=;i<=m;i++){
f=;
for(j=;j<=n;j++){
if(g[j][i]==) f=;
if(g[j][i]!=&&!f) col++,f=;
if(g[j][i]!=)
beg[j][i]=col;
}
}
for(i=;i<=n;i++){
f=;
for(j=;j<=m;j++){
if(g[i][j]==) f=;
if(g[i][j]!=&&!f) row++,f=;
if(g[i][j]!=)
gg[i][j]=row;
}
}
for(i=;i<=row;i++){
add1(,i,);
}
for(i=;i<=col;i++){
add1(i+row,row+col+,);
}
for(i=;i<=n;i++){
for(j=;j<=m;j++){
if(g[i][j]==){
add1(gg[i][j],beg[i][j]+row,);
}
}
}
}
int main()
{
int n,m,i,j,num=,t,x,y,p,w;
scanf("%d",&t);
while(t--){
init();
memset(g,,sizeof(g));
memset(beg,,sizeof(beg));
memset(gg,,sizeof(gg));
scanf("%d%d",&n,&m);
scanf("%d",&p);
for(i=;i<=p;i++){
scanf("%d%d",&x,&y);
g[x][y]=;
}
scanf("%d",&w);
for(i=;i<=w;i++){
scanf("%d%d",&x,&y);
g[x][y]=;
}
build(n,m);
if(row==||col==||p==){
printf("0\n");
continue;
}
int ans=Dinic(,row+col+);
printf("%d\n",ans);
}
return ;
}

最新文章

  1. PHP相关笔记
  2. C#编写window服务,一步一步(1)
  3. iOStextFiled判断输入长度
  4. [CareerCup] 2.3 Delete Node in a Linked List 删除链表的节点
  5. 使用ffmpeg快速生成视频截图
  6. sharepoint 2013 sp1
  7. HDU-3790 最短路径问题
  8. 如何在客户端配置ODBC来访问远程DB2 for Windows服务器
  9. [BZOJ 3129] [Sdoi2013] 方程 【容斥+组合数取模+中国剩余定理】
  10. 数学计数原理(P&#243;lya):POJ 1286 Necklace of Beads
  11. mybatis 关联关系查询 java
  12. IDEA github的应用
  13. win8.1 64位+oracle11g R2 64位 +powerdesigner破解版 64位+PL/SQL
  14. fastboot烧写hi3531
  15. Learning ROS for Robotics Programming Second Edition学习笔记(七) indigo PCL xtion pro live
  16. zabbix-agent(zabbix-proxy)配置
  17. 显存充足,但是却出现CUDA error:out of memory错误
  18. MVC控制器传递多个实体类集合到视图的方案总结
  19. (转)webpack和webpack-simple区别(如何引入css文件)
  20. 大批量delete 优化方案

热门文章

  1. log4.net
  2. 转载:linux vi命令详解
  3. Javascript(JS)对Cookie的读取、删除、写入操作帮助方法
  4. word2013中取消句首字母自动大写
  5. Java常见排序算法之冒泡排序
  6. Java学习笔记之==与equals
  7. Python 数据类型
  8. XPath具体解释
  9. 【C#】ASP.NET网页中添加单点登录功能
  10. vim编码相关配置