zoukankan      html  css  js  c++  java
  • BZOJ 1433: [ZJOI2009]假期的宿舍

    二次联通门 : BZOJ 1433: [ZJOI2009]假期的宿舍

    /*
        BZOJ 1433: [ZJOI2009]假期的宿舍
        
        
        建图时分为两个集合
        床一个集合
        人一个集合
        S到床连边
        人与自己认识的人连边
        人与T点连边
        
        然后跑最大流判断即可 
    */
    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <queue>
    
    #define Max 300
    #define INF 1e7
    
    using namespace std;
    
    inline int min (int a, int b)
    {
        return a < b ? a : b;
    }
    
    void read (int &now)
    {
        now = 0;
        char word = getchar ();
        while (word > '9' || word < '0')
            word = getchar ();
        while (word >= '0' && word <= '9')
        {
            now = now * 10 + word - '0';
            word = getchar ();
        }
    }
    
    int S, T;
    
    struct Edge
    {
        int to;
        int next;
        int flow;
    }edge[Max << 6];
    
    int Edge_Count = 1;
    int edge_list[Max];
    
    int N, M;
    int is[Max];
    
    inline void AddEdge (int from, int to)
    {
        Edge_Count++;
        edge[Edge_Count].to = to;
        edge[Edge_Count].flow = 1;
        edge[Edge_Count].next = edge_list[from];
        edge_list[from] = Edge_Count;
        Edge_Count++;
        edge[Edge_Count].to = from;
        edge[Edge_Count].flow = 0;
        edge[Edge_Count].next = edge_list[to];
        edge_list[to] = Edge_Count;
    }
    
    int deep[Max];
    
    int Flowing (int now, int flow)
    {
        if (flow <= 0 || now == T)
            return flow;
        int res = 0, pos;
        for (int i = edge_list[now]; i; i = edge[i].next)
        {
            if (deep[edge[i].to] != deep[now] + 1 || edge[i].flow <= 0)
                continue;
            pos = Flowing (edge[i].to, min (flow, edge[i].flow));
            flow -= pos;
            res += pos;
            edge[i].flow -= pos;
            edge[i ^ 1].flow += pos;
            if (flow <= 0)
                return res;        
        }
        return res;
    }
    
    
    int main (int argc, char *argv[])
    {
        int G;
        read (G);
        while (G--)
        {
            read (N);
            memset (edge_list, 0, sizeof edge_list);
            memset (is, 0, sizeof is);
            S = 0;
            T = Max - 1;
            Edge_Count = 1;
            int Fact = N;
            for (int i = 1; i <= N; i++)
            {
                read (is[i]);
                if (is[i])
                    AddEdge (N + i, T);
            }
            int x;
            int Answer = 0;
            for (int i = 1; i <= N; i++)
            {
                read (x);
                if (is[i])
                {
                    if (!x)
                        AddEdge (S, i);
                    else
                        Fact--;
                }
                else
                    AddEdge (S, i);
            }
            for (int i = 1; i <= N; i++)
            {
                if (is[i])
                    AddEdge (i, i + N);
                for (int j = 1; j <= N; j++)
                {
                    read (x);
                    if (x)
                        AddEdge (i, j + N);
                }
            }
            while (true)
            {
                bool flag = false;
                memset (deep, -1, sizeof deep);
                queue <int> Queue;
                Queue.push (S);
                deep[S] = 0; 
                int now;
                while (!Queue.empty ())
                {
                    now = Queue.front ();
                    Queue.pop ();
                    for (int i = edge_list[now]; i; i = edge[i].next) 
                        if (deep[edge[i].to] < 0 && edge[i].flow)
                        {
                            deep[edge[i].to] = deep[now] + 1;
                            if (edge[i].to == T)
                            {
                                flag = true;
                                break;
                            }
                            Queue.push (edge[i].to); 
                        }
                    if (flag)
                        break;
                }
                if (deep[T] < 0)
                    break;
                Answer += Flowing (S, INF);
            }
            printf (Answer >= Fact ? "^_^
    " : "T_T
    ");
        }
        return 0;
    }
  • 相关阅读:
    小型的Unix系统字符SHELL
    小型的Unix系统字符SHELL
    string 大小写转换
    string 大小写转换
    string 大小写转换
    ACM 的中取模
    ACM 的中取模
    使用adb命令停止APP后台进程的方法
    how to use adb and gdbserver with VirtualBox
    CentOS的KVM实践(虚拟机创建、网桥配置、Spice)
  • 原文地址:https://www.cnblogs.com/ZlycerQan/p/6882691.html
Copyright © 2011-2022 走看看