• [bzoj1433][ZJOI2009]假期的宿舍——二分图


    题目大意

    传送门

    题解

    显然是二分图匹配。
    用一些方法建图就好了。
    要注意的是:
    本题有多组数据!!!
    初始化一定要注意!!!

    代码

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 505;
    const int inf = 0x3f3f3f;
    int n;
    // 1~n:学生
    // n+1~n+k:床位
    int isbed[maxn], insch[maxn];
    int dist[maxn * 2], iter[maxn * 2];
    struct edge {
      int to, cap, rev;
    };
    vector<edge> G[maxn];
    void add_edge(int from, int to, int cap) {
      G[from].push_back((edge){to, cap, G[to].size()});
      G[to].push_back((edge){from, 0, G[from].size() - 1});
    }
    int cnt = 0;
    void read() {
      scanf("%d", &n);
      memset(isbed, 0, sizeof(isbed));
      for (int i = 0; i <= 2 * n + 1; i++) {
        G[i].clear();
      }
      cnt = 0;
      for (int i = 1; i <= n; i++) {
        scanf("%d", &isbed[i]);
      }
      for (int i = 1; i <= n; i++) {
        scanf("%d", &insch[i]);
        insch[i] = insch[i] ^ 1;
      }
      for (int i = 1; i <= n; i++) {
        if (isbed[i])
          add_edge(i, i + n, 1);
        for (int j = 1; j <= n; j++) {
          int x;
          scanf("%d", &x);
          if (x && isbed[j]) {
            if (!(isbed[i]) || (isbed[i] && insch[i])) {
              add_edge(i, n + j, 1);
            }
          }
        }
        if (!(isbed[i]) || (isbed[i] && insch[i])) {
          cnt++;
          add_edge(0, i, 1);
        }
     
        if (isbed[i])
          add_edge(n + i, 2 * n + 1, 1);
      }
    }
    void bfs(int from) {
      memset(dist, -1, sizeof(dist));
      dist[from] = 0;
      queue<int> q;
      q.push(from);
      while (!q.empty()) {
        int u = q.front();
        q.pop();
        for (int i = 0; i < G[u].size(); i++) {
          edge &e = G[u][i];
          if (dist[e.to] < 0 && e.cap > 0) {
            dist[e.to] = dist[u] + 1;
            q.push(e.to);
          }
        }
      }
    }
    int dfs(int from, int to, int f) {
      if (from == to)
        return f;
      for (int &i = iter[from]; i < G[from].size(); i++) {
        edge &e = G[from][i];
        if (e.cap > 0 && dist[e.to] > dist[from]) {
          int d = dfs(e.to, to, min(f, e.cap));
          if (d > 0) {
            e.cap -= d;
            G[e.to][e.rev].cap += d;
            return d;
          }
        }
      }
      return 0;
    }
    int max_flow(int from, int to) {
      int flow = 0;
      for (;;) {
        bfs(from);
        if (dist[to] < 0)
          return flow;
        memset(iter, 0, sizeof(iter));
        int f;
        while ((f = dfs(from, to, inf) > 0))
          flow += f;
      }
    }
    int main() {
      //  freopen("input", "r", stdin);
      int T;
      scanf("%d", &T);
      while (T--) {
        cnt = 0;
        read();
        int ans = max_flow(0, 2 * n + 1);
        if (ans == cnt)
          printf("^_^
    ");
        else
          printf("T_T
    ");
      }
      return 0;
    }
    
  • 相关阅读:
    Mac使用笔记(二)
    AJAX tooltip by jQuery UI Widget and MVC3
    MVC4的bundling功能简介
    Mac使用笔记
    浅析ASP.Net Web API的Formatter
    浅析ASP.net Web API的Model验证(使用MVC4框架的Web API须谨慎)
    2012年读过的最好的书
    SQLite在.net下的使用方法
    C#也允许函数默认参数
    chrome不支持对opener方法的调用?
  • 原文地址:https://www.cnblogs.com/gengchen/p/6402818.html
Copyright © 2020-2023  润新知