poj 1486 网络流+tarjan

来源:互联网 发布:python split 多个空格 编辑:程序博客网 时间:2024/05/16 01:35

题意:给一堆矩形和一些点,每个矩形必须对应一个点,求对应的点唯一的矩形个数。

如果点在矩形内部那么从点向矩形连流量1的边,从S向点连流量1的边,从矩形向T连流量1的边。跑网络流。

跑出来的东西是一种方案。将这种方案变成另一种方案只需要找到所有边剩余流量都为1的环,这样的环一定是偶环且正向边和反向边交替排列。那么把正向边流量流掉,把反向边流量退回就是一种新方案。

那么只需要跑一遍tarjan,如果矩形和在网络流中和他匹配的点不在一个强连通分量中,那么这个矩形的方案就是唯一的。

#include <queue>#include <stdio.h>#include <string.h>#include <algorithm>using namespace std;#define N 1100#define inf 1e9#define M 2100000int n,Case;int X1[N],X2[N],Y1[N],Y2[N];struct awork_flow{    int head[N<<1],nex[M],to[M],val[M],tot;    int deep[N<<1],S,T;    queue<int>que;    void init()    {        memset(head,0,sizeof(head));        tot=1;    }    void add(int x,int y,int z)    {        tot++;        nex[tot]=head[x];head[x]=tot;        to[tot]=y;val[tot]=z;    }    int dfs(int x,int mv)    {        if(x==T)return mv;        int tmp=0;        for(int i=head[x];i;i=nex[i])            if(val[i]&&deep[to[i]]==deep[x]+1)            {                int t=dfs(to[i],min(mv-tmp,val[i]));                if(!t)deep[to[i]]=-1;                tmp+=t;val[i]-=t;                val[i^1]+=t;                if(tmp==mv)break;            }        return tmp;    }    int bfs()    {        while(!que.empty())que.pop();        que.push(S);        memset(deep,-1,sizeof(deep));        deep[S]=0;        while(!que.empty())        {            int tmp=que.front();que.pop();            for(int i=head[tmp];i;i=nex[i])                if(val[i]&&deep[to[i]]==-1)                {                    deep[to[i]]=deep[tmp]+1;                    if(to[i]==T)return 1;                    que.push(to[i]);                }        }        return 0;    }    int dinic()    {        int ret=0;        while(bfs())            ret+=dfs(S,inf);            return ret;    }}a;struct Tarjan{    int dfn[N<<1],low[N<<1],bel[N<<1];    int st[N<<1],top,cnt,ins[N<<1],tot;    void init()    {        top=0;cnt=0;tot=0;        memset(dfn,0,sizeof(dfn));        memset(low,0,sizeof(low));    }    void tarjan(int x)    {        dfn[x]=low[x]=++cnt;st[++top]=x;        ins[x]=1;        for(int i=a.head[x];i;i=a.nex[i])            if(a.val[i])            {                if(!dfn[a.to[i]])tarjan(a.to[i]),low[x]=min(low[x],low[a.to[i]]);                else if(ins[a.to[i]])low[x]=min(low[x],dfn[a.to[i]]);            }        if(dfn[x]==low[x])        {            int t=st[top--];bel[t]=++tot;            ins[t]=0;            while(t!=x)            {                t=st[top--];                bel[t]=tot;ins[t]=0;            }        }    }}b;int main(){    while(scanf("%d",&n)!=EOF&&n)    {        for(int i=1;i<=n;i++)            scanf("%d%d%d%d",&X1[i],&X2[i],&Y1[i],&Y2[i]);        a.init();b.init();        for(int i=1,x,y;i<=n;i++)        {            scanf("%d%d",&x,&y);            for(int j=1;j<=n;j++)                if(X1[j]<=x&&X2[j]>=x&&Y1[j]<=y&&Y2[j]>=y)                    a.add(i+n,j,1),a.add(j,i+n,0);        }        a.S=n*2+1;a.T=n*2+2;        for(int i=1;i<=n;i++)a.add(a.S,i+n,1),a.add(i+n,a.S,0);        for(int i=1;i<=n;i++)a.add(i,a.T,1),a.add(a.T,i,0);        a.dinic();        for(int i=1;i<=a.T;i++)            if(!b.dfn[i])b.tarjan(i);        int cnt=0;        printf("Heap %d\n",++Case);        for(int i=1;i<=n;i++)            for(int j=a.head[i];j;j=a.nex[j])                if(a.val[j]&&a.to[j]>n&&a.to[j]<a.S&&b.bel[i]!=b.bel[a.to[j]])                {                    cnt++;                    printf("(%c,%d) ",i+'A'-1,a.to[j]-n);                }        if(!cnt)puts("none");        else puts("");        puts("");    }    return 0;}
0 0
原创粉丝点击