uva 12549 最大流

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

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

#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-9;
LL value[Maxn];
int head[Maxn],work[Maxn],dis[Maxn],q[Maxn],e,vi[Maxn];
void init()
{
    e=0;
    memset(head,-1,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=0;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=0;
    memset(dis,-1,sizeof(dis));
    dis[S]=0;q[rear++]=S;
    for(int i=0;i<rear;i++)
    {
        for(int j=head[q[i]];j!=-1;j=edge[j].next)
        {
            if(edge[j].val&&dis[edge[j].to]==-1)
            {
                dis[edge[j].to]=dis[q[i]]+1;
                q[rear++]=edge[j].to;
                if(edge[j].to==T) return 1;
            }
        }
    }
    return 0;
}
LL dfs(int cur,LL a,int T)
{
    if(cur==T) return a;
    for(int &i=work[cur];i!=-1;i=edge[i].next)
    {
        if(edge[i].val&&dis[edge[i].to]==dis[cur]+1)
        {
            LL t=dfs(edge[i].to,min(a,edge[i].val),T);
            if(t)
            {
                edge[i].val-=t;
                edge[i^1].val+=t;
                return t;
            }
        }
    }
    return 0;
}
LL Dinic(int S,int T)
{
    LL ans=0;
    while(bfs(S,T))
    {
        memcpy(work,head,sizeof(head));
        while(LL t=dfs(S,inf,T)) ans+=t;
    }
    return ans;
}
int g[110][110],row,col,beg[110][110],gg[110][110];
void build(int n,int m)
{
    int i,j,f=0;
    row=col=0;
    for(i=1;i<=m;i++){
        f=0;
        for(j=1;j<=n;j++){
            if(g[j][i]==2) f=0;
            if(g[j][i]!=2&&!f) col++,f=1;
            if(g[j][i]!=2)
                beg[j][i]=col;
        }
    }
    for(i=1;i<=n;i++){
        f=0;
        for(j=1;j<=m;j++){
            if(g[i][j]==2) f=0;
            if(g[i][j]!=2&&!f) row++,f=1;
            if(g[i][j]!=2)
                gg[i][j]=row;
        }
    }
    for(i=1;i<=row;i++){
        add1(0,i,1);
    }
    for(i=1;i<=col;i++){
        add1(i+row,row+col+1,1);
    }
    for(i=1;i<=n;i++){
        for(j=1;j<=m;j++){
            if(g[i][j]==1){
                add1(gg[i][j],beg[i][j]+row,1);
            }
        }
    }
}
int main()
{
    int n,m,i,j,num=0,t,x,y,p,w;
    scanf("%d",&t);
    while(t--){
        init();
        memset(g,0,sizeof(g));
        memset(beg,0,sizeof(beg));
        memset(gg,0,sizeof(gg));
        scanf("%d%d",&n,&m);
        scanf("%d",&p);
        for(i=1;i<=p;i++){
            scanf("%d%d",&x,&y);
            g[x][y]=1;
        }
        scanf("%d",&w);
        for(i=1;i<=w;i++){
            scanf("%d%d",&x,&y);
            g[x][y]=2;
        }
        build(n,m);
        if(row==0||col==0||p==0){
            printf("0\n");
            continue;
        }
        int ans=Dinic(0,row+col+1);
        printf("%d\n",ans);
    }
    return 0;
}

 

posted @ 2013-10-04 15:57  fangguo  阅读(347)  评论(0编辑  收藏  举报