[Maximum flow, dinic] P2055 [ZJOI2009] holiday hostel

  1 #include<iostream>
  2 #include<queue>
  3 #include<cstring>
  4 using namespace std;
  5 
  6 const int maxn = 60;
  7 
  8 const int INF = 0x3f3f3f3f;
  9 int n;
 10 int head[maxn << 2 | 1];
 11 int cnt;
 12 int d[maxn << 2 | 1];
 13 int now[maxn << 2 | 1];
 14 int school[maxn];
 15 int home[maxn];
 16 int st, ed;
 17 
 18 struct Edge
 19 {
 20     int v, nxt, w;
 21 }e[maxn << 4 | 1];
 22 
 23 void add_dinic(int u, int v)
 24 {
 25     e[++cnt].v = v;
 26     e[cnt].w = 0;
 27     e[cnt].nxt = head[u];
 28     head[u] = cnt;
 29 }
 30 
 31 inline void add(int u, int v, int w)
 32 {
 33     e[++cnt].v = v;
 34     e[cnt].w = w;
 35     e[cnt].nxt = head[u];
 36     head[u] = cnt;
 37     add_dinic(v, u);
 38 }
 39 
 40 int dfs_dinic(int x, int flow)
 41 {
 42     if (x == ed) return flow;
 43     int res = 0;
 44     for (int i = now[x]; i != -1; i = e[i].nxt)
 45     {
 46         int v = e[i].v;
 47         if (d[v] + 1 == d[x] && e[i].w > 0)
 48         {
 49             int k = dfs_dinic(v, min(e[i].w, flow));
 50             res += k;
 51             flow -= k;
 52             e[i].w -= k;
 53             e[i ^ 1].w += k;
 54             if (!flow) break;
 55         }
 56     }
 57     return res;
 58 }
 59 
 60 bool bfs_dinic()
 61 {
 62     memset(d, 0, sizeof(d));
 63     queue<int>q;
 64     q.push(ed);
 65     d[ed] = 1;
 66     while (!q.empty())
 67     {
 68         int u = q.front();
 69         q.pop();
 70         for (int i = head[u]; i != -1; i = e[i].nxt)
 71         {
 72             int v = e[i].v;
 73             if (!d[v] && e[i ^ 1].w > 0)
 74             {
 75                 q.push(v);
 76                 d[v] = d[u] + 1;
 77             }
 78         }
 79     }
 80     return d[st] > 0;
 81 }
 82 
 83 
 84 int dinic() 
 85 {
 86     int flow = 0;
 87     while (bfs_dinic()) 
 88     {
 89         for (int i = 0; i <= ed; i++) now[i] = head[i];
 90         flow += dfs_dinic(st, INF);
 91     }
 92     return flow;
 93 }
 94 
 95 int main()
 96 {
 97     int T;
 98     cin >> T;
 99     while (T--)
100     {
101         memset(head, -1, sizeof(head));
102         cnt = 1;
103         //源点0,汇点2n+1
104         cin >> n;
105         int tot = 0;
106         st = 0;
107         ed = n << 1 | 1;
108         for (int i = 1; i <= n; i++)
109         {
110             cin >> school[i];
111             if(school[i]) add(i + n, ed, 1);
112         }
113         for (int i = 1; i <= n; i++)
114         {
115                 cin >> home[i];
116                 if ((!home[i] && school[i]) || !school[i]) add(st, i, 1), tot++;
117         }
118         for (int i = 1; i <= n; i++)
119         {
120             for (int j = 1; j <= n; j++)
121             {
122                 int t;
123                 cin >> t;
124                 if (t || i == j) add(i, j + n, 1);
125             }
126         }
127         int ans = 0;
128         ans = dinic();
129         if (ans >= tot) cout << "^_^" << endl;
130         else cout << "T_T" << endl;
131         memset(now, 0, sizeof(now));
132     }
133 }
View Code

 

Guess you like

Origin www.cnblogs.com/thjkhdf12/p/11823724.html