uva 12549 最大流

时间:2021-04-01 07:07:30

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

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

#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 ;
}