• BZOJ-1433 假期的宿舍 最大流+基础建图


    网络流练习ing。。
    

    1433: [ZJOI2009]假期的宿舍
    Time Limit: 10 Sec Memory Limit: 162 MB
    Submit: 1748 Solved: 765
    [Submit][Status][Discuss]

    Description
    这里写图片描述

    Input
    这里写图片描述

    Output
    这里写图片描述

    Sample Input
    1
    3
    1 1 0
    0 1 0
    0 1 1
    1 0 0
    1 0 0

    **Sample Outpu**t
    ˆ-ˆ

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

    基础建图:
    超级源连向所有在校生(有床位的人);所有在校生且不回家的,与所有非在校生的与超级源相连;每个点分成两个i与i',如果i和j认识连i与j';边权全部为1
    最大流即为答案。
    

    代码:

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    #define M 1000010
    struct data{
         int  to,next,v;
    }edge[M];
    int head[M],cnt=1;
    int dis[M];
    int q[M],h,t;
    int c,n,ans,num;
    int zx[60],know[60][60],hj[60];
     //zx【】是否在校,know【】【】是否认识,hj【】是否回家
    
    void add(int u,int v,int w)
    {
        cnt++;
        edge[cnt].to=v;
        edge[cnt].next=head[u];
        head[u]=cnt;
        edge[cnt].v=w;
    }
    
    void make()//超级源为0,超级汇为2*n+1
    {
        cnt=1;  memset(head,0,sizeof(head));
        num=0;
        for (int i=1; i<=n; i++)
            for (int j=1; j<=n; j++)
                if (know[i][j]==1)
                    {
                        add(i,j+n,1);
                        add(j+n,i,0);
                    }
        for (int i=1; i<=n; i++)
            {
                if (zx[i]==1)
                    {
                        add(0,i,1);
                        add(i,0,0);
                    }
                if ((zx[i]==1 && hj[i]==0) || (zx[i]==0))
                    {
                        add(i+n,2*n+1,1);
                        add(2*n+1,i+n,0);
                        num++;//需要床位数
                    }
            }
    }
    
    bool bfs()
    {
        memset(dis,-1,sizeof(dis));
        q[1]=0; dis[0]=1;
        h=0; t=1;
        while (h<t)
            {
                int j=q[++h],i=head[j];
                while (i)
                    {
                        if (edge[i].v>0 && dis[edge[i].to]<0)
                            {
                                dis[edge[i].to]=dis[j]+1;
                                q[++t]=edge[i].to;
                            }
                        i=edge[i].next;
                    }
            }
        if (dis[2*n+1]>0)
            return true;
        else
            return false;   
    }
    
    int dfs(int loc,int low)
    {
        int flow=0;
        if (loc==2*n+1) return low;
        int i=head[loc];
        while (i)
            {
                if (edge[i].v>0 && dis[edge[i].to]==dis[loc]+1 && (flow=dfs(edge[i].to,min(low,edge[i].v))))
                    {
                        edge[i].v-=flow;
                        edge[i^1].v+=flow;
                        return flow;
                    }
                i=edge[i].next;
            }
        return 0;
    }
    
    int main()
    {
        scanf("%d",&c);
        while (c--)
            {
                scanf("%d",&n);
                memset(zx,0,sizeof(zx));
                memset(hj,0,sizeof(hj));
                memset(know,0,sizeof(know));
                for (int i=1; i<=n; i++)
                    scanf("%d",&zx[i]);
                for (int i=1; i<=n; i++)
                    scanf("%d",&hj[i]);
                for (int i=1; i<=n; i++)
                    for (int j=1; j<=n; j++)
                        scanf("%d",&know[i][j]);
                for (int i=1; i<=n; i++)
                    know[i][i]=1;//由题意自己和自己在读入时为不能睡,但实际可以,修改。
                make();
                ans=0;
                while (bfs())
                    {
                        int now=0;
                        while ((now=dfs(0,0x7fffffff)))
                            ans+=now;
                    }
                if  (num==ans)
                    puts("^_^");
                else
                    puts("T_T");        
            }
        return 0;
    }
  • 相关阅读:
    cpp 二进制文件读写
    中文词频统计
    文件方式实现完整的英文词频统计实例
    组合数据类型练习,英文词频统计实例上
    英文词频统计预备,组合数据类型练习
    凯撒密码、GDP格式化输出、99乘法表
    字符串基本操作
    条件、循环、函数定义 练习
    turtle库基础练习
    Python基础练习
  • 原文地址:https://www.cnblogs.com/DaD3zZ-Beyonder/p/5346230.html
Copyright © 2020-2023  润新知