• bzoj 1433: [ZJOI2009]假期的宿舍 -- 最大流


    1433: [ZJOI2009]假期的宿舍

    Time Limit: 10 Sec  Memory Limit: 162 MB

    Description

    Input

    Output

    Sample Input

    1
    3
    1 1 0
    0 1 0
    0 1 1
    1 0 0
    1 0 0

    Sample Output

    ˆ ˆ

    HINT

    对于30% 的数据满足1 ≤ n ≤ 12。
    对于100% 的数据满足1 ≤ n ≤ 50,1 ≤ T ≤ 20。

    我们从源点向所有住宿的人连边,从所有的床位连向汇点,然后再从人连向他所认识的人的床位

    这样建边,然后跑最大流

    这样答案如果和住宿人数相等则满足,否则不满足

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define inf 100007
    #define F(i) for(i=1;i<=n;i++)
    #define N 50010
    #define M 110
    inline int rd()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    int lj[M],fro[N],to[N],cnt,v[N],S,T=101;
    inline void add(int a,int b,int c){fro[++cnt]=lj[a];to[cnt]=b;v[cnt]=c;lj[a]=cnt;}
    inline void ins(int a,int b,int c){add(a,b,c);add(b,a,0);}
    int dis[M],q[N],h,t;
    bool bfs()
    {
        memset(dis,0,sizeof(dis));
        dis[0]=h=t=1;q[1]=0;
        int tp;
        while(h<=t)
        {
            tp=q[h++];
            for(int i=lj[tp];i;i=fro[i])
            {
                if(!dis[to[i]]&&v[i])
                {
                    dis[to[i]]=dis[tp]+1;
                    q[++t]=to[i];
                }
            }
        }
        return dis[T]?1:0;
    }
    int dfs(int x,int p)
    {
        if(x==T) return p;
        int tp,res=0;
        for(int i=lj[x];i;i=fro[i])
        {
            if(v[i]&&dis[to[i]]==dis[x]+1)
            {
                tp=dfs(to[i],min(p-res,v[i]));
                v[i]-=tp; 
                v[i^1]+=tp;
                res+=tp;
                if(res==p) return p;
            }
        }
        if(res==0)  dis[x]=0;
        return res;
    }
    int n,tt,sc[M],tot,ans;
    int main()
    {
        tt=rd();
        int i,j,x;
        while(tt--)
        {
            tot=ans=0;
            memset(lj,0,sizeof(lj));cnt=1;
            n=rd();
            F(i){
                sc[i]=rd();
                if(sc[i]) ins(i+n,T,1);
            }
            F(i){
                x=rd();
                if((sc[i]&&!x)||!sc[i])
                {
                    ins(0,i,1);
                    tot++;
                }
            }
            F(i) F(j)
            {
                x=rd();
                if(x||i==j) ins(i,j+n,1);
            }
            while(bfs()) ans+=dfs(0,inf);
            if(tot==ans) puts("^_^");
            else puts("T_T");
        }
    }

    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    except与besides
    think用法
    walk用法
    complain用法
    go through用法
    herd用法
    ridiculous用法
    it is the same as用法
    let us say用法
    1002 A+B for Polynomials (25 分)(模拟)
  • 原文地址:https://www.cnblogs.com/lkhll/p/6741263.html
Copyright © 2020-2023  润新知