HDU3605 Escape

Posted ---学习ing---

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU3605 Escape相关的知识,希望对你有一定的参考价值。

思想:缩点+sap

Max,t还可以缩小,优化,高数课写的,有点丑,暂时懒得改。

 

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<memory.h>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
const int maxm=401000;
const int inf=0x7fffffff;
int vd[maxm],dis[maxm];
int Laxt[maxm],Next[maxm],To[maxm],V[maxm];
int n,m,cnt,ans,s,t;
int a[maxm],c[maxm];
void _update()
{
    memset(Laxt,0,sizeof(Laxt));
    memset(dis,0,sizeof(dis));
    memset(vd,0,sizeof(vd));
    memset(a,0,sizeof(a));
    memset(c,0,sizeof(c));
    cnt=2;
    ans=0;
}
void _add(int u,int v,int c)
{
    Next[cnt]=Laxt[u];
    Laxt[u]=cnt;
    To[cnt]=v;
    V[cnt++]=c;
    Next[cnt]=Laxt[v];
    Laxt[v]=cnt;
    To[cnt]=u;
    V[cnt++]=0;
}
int _sap(int u,int flow)
{
    int tmp,delta=0;
    if(flow==0||u==t) return flow;
    for(int i=Laxt[u];i;i=Next[i])
    {
        if(dis[To[i]]+1==dis[u]&&V[i]>0){
            tmp=_sap(To[i],min(flow-delta,V[i]));
            V[i]-=tmp;
            V[i^1]+=tmp;
            delta+=tmp;
            if(delta==flow||dis[s]>t) return delta;
        }
    }
    vd[dis[u]]--;
    if(vd[dis[u]]==0) dis[s]=t+1;
    vd[++dis[u]]++;
    return delta;
}
int main()
{
    int n,m,i,j,Max,x;
    while(~scanf("%d%d",&n,&m))
    {
         _update();
         Max=0;
         for(i=1;i<=n;i++){
            int tmp=0;
            for(j=1;j<=m;j++) {
               scanf("%d",&x);
               tmp=tmp*2+x;
            }
            if(tmp>Max) Max=tmp;
            a[tmp]++;
         }
         s=0;t=Max+m+1;
         for(i=1;i<=m;i++) scanf("%d",&c[i]);
         for(i=1;i<=Max;i++){
                if(a[i]>0) {
                    _add(0,i,a[i]);
                    int k=m,p=i;
                    while(k&&p){
                        int tmp=p%2;
                        p/=2;
                        if(tmp>0) _add(i,Max+k,inf);
                        k--;
                    }
                }
         }
         for(i=1;i<=m;i++) _add(Max+i,t,c[i]);
         while(dis[s]<=t) {
                ans+=_sap(s,inf);
         }
         if(ans==n) printf("YES\n");
         else printf("NO\n");
    }
    return 0;
}

 

以上是关于HDU3605 Escape的主要内容,如果未能解决你的问题,请参考以下文章

HDU 3605 Escape(状压+最大流)

HDU 3605 Escape(二分图多重匹配问题)

hdu 3605 Escape 二分图的多重匹配(匈牙利算法)

HDU 3605 Escape(状态压缩+最大流)

hdu 3605 Escape 二分图的多重匹配(匈牙利算法)

HDU3605: Escape-二进制优化建图-最大流