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

    题意:自行脑补

    思路:网络流。建模显然,若满流则能够

    代码:

    #include <cstdio>
    #include <cstring>
    #include <cctype>
    #include <iostream>
    #include <algorithm>
    #include <queue>
    using namespace std;
     
    #define INF 0x3f3f3f3f
     
    queue<int> q;
    struct Solver {
        int head[200], next[6010], end[6010], flow[6010], ind;
        int gap[200], d[200], stack[200], top, cur[200];
        void reset() {
            ind = top = 0;
            memset(head, -1, sizeof(head));
        }
        void addedge(int a, int b, int _flow) {
            int q = ind++;
            end[q] = b;
            next[q] = head[a];
            head[a] = q;
            flow[q] = _flow;
        }
        void make(int a, int b, int _flow) {
            //printf("%d %d
    ", a, b);
            addedge(a, b, _flow);
            addedge(b, a, 0);
        }
        void bfs(int T) {
            memset(d, -1, sizeof d);
            memset(gap, 0, sizeof gap);
            ++gap[d[T] = 0];
            q.push(T);
            register int i, j;
            while(!q.empty()) {
                i = q.front();
                q.pop();
                for(j = head[i]; j != -1; j = next[j])
                    if (d[end[j]] == -1)
                        ++gap[d[end[j]] = d[i] + 1], q.push(end[j]);
            }
        }
        int Maxflow(int S, int T) {
            bfs(T);
            memcpy(cur, head, sizeof cur);
            int u = S, res = 0, i, ins, Min;
            while(d[S] < T - S + 1) {
                if (u == T) {
                    Min = INF;
                    for(i = 0; i < top; ++i)
                        if (flow[stack[i]] < Min)
                            Min = flow[stack[i]], ins = i;
                    for(i = 0; i < top; ++i)
                        flow[stack[i]] -= Min, flow[stack[i] ^ 1] += Min;
                    res += Min;
                    u = end[stack[top = ins] ^ 1];
                }
                if (u != T && !gap[d[u] - 1])
                    break;
                bool find = 0;
                for(int &j = cur[u]; j != -1; j = next[j])
                    if (flow[j] && d[end[j]] + 1 == d[u]) {
                        find = 1;
                        ins = j;
                        break;
                    }
                if (find) {
                    cur[u] = ins;
                    stack[top++] = ins;
                    u = end[ins];
                }
                else {
                    Min = T - S + 1;
                    for(int j = head[u]; j != -1; j = next[j]) {
                        if (flow[j] && Min > d[end[j]]) {
                            Min = d[end[j]];
                            cur[u] = j;
                        }
                    }
                    if (!--gap[d[u]])
                        break;
                    ++gap[d[u] = Min + 1];
                    if (u != S)
                        u = end[stack[--top] ^ 1];
                }
            }
            return res;
        }
    }G;
     
    int is_student[51], is_at_home[51], M[51][51];
    int main() {
        int T;
        scanf("%d", &T);
         
        while(T--) {
             
            int n;
            scanf("%d", &n);
             
            register int i, j;
            for(i = 1; i <= n; ++i)
                scanf("%d", &is_student[i]);
            for(i = 1; i <= n; ++i)
                scanf("%d", &is_at_home[i]);
            for(i = 1; i <= n; ++i)
                for(j = 1; j <= n; ++j)
                    scanf("%d", &M[i][j]);
            for(i = 1; i <= n; ++i)
                M[i][i] = 1;
             
            G.reset();
            int size = 0;
            for(i = 1; i <= n; ++i)
                if ((is_student[i] && !is_at_home[i]) || !is_student[i])
                    G.make(0, i, 1), ++size;
            for(i = 1; i <= n; ++i)
                if (is_student[i])
                    G.make(n + i, 2 * n + 1, 1);
            for(i = 1; i <= n; ++i)
                for(j = 1; j <= n; ++j)
                    if (M[i][j])
                        G.make(i, n + j, 1);
             
            int res = G.Maxflow(0, 2 * n + 1);
            if (res == size)
                puts("^_^");
            else
                puts("T_T");
        }
         
        return 0;
    }

  • 相关阅读:
    第十七节:织梦做自定义表单在线预约的方法
    ExecuteNonQuery()返回值
    WCF服务编程读书笔记(6):错误
    ubuntu 工作区切换快捷键设置
    a pubhub service
    淘宝提供了Rubygems的国内镜像站点 ruby rails源
    新rails安装过程记录
    XMLRPC HOWTO
    XMLRPC HOWTO
    metaweblog api相关
  • 原文地址:https://www.cnblogs.com/tlnshuju/p/6882395.html
Copyright © 2011-2022 走看看