UVA1184 Air Raid

嘟嘟嘟

 

最小路径覆盖板子题。

建二分图,然后跑Dinic(因为我不会匈牙利),然后ans = n - maxflow()。

主要是发一下用链前存图的写法。(好像比vector短一点)

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<cmath>
  4 #include<algorithm>
  5 #include<cstring>
  6 #include<cstdlib>
  7 #include<cctype>
  8 #include<vector>
  9 #include<stack>
 10 #include<queue>
 11 using namespace std;
 12 #define enter puts("") 
 13 #define space putchar(' ')
 14 #define Mem(a, x) memset(a, x, sizeof(a))
 15 #define rg register
 16 typedef long long ll;
 17 typedef double db;
 18 const int INF = 0x3f3f3f3f;
 19 const db eps = 1e-8;
 20 const int maxn = 1e5 + 5;
 21 inline ll read()
 22 {
 23   ll ans = 0;
 24   char ch = getchar(), last = ' ';
 25   while(!isdigit(ch)) {last = ch; ch = getchar();}
 26   while(isdigit(ch)) {ans = ans * 10 + ch - '0'; ch = getchar();}
 27   if(last == '-') ans = -ans;
 28   return ans;
 29 }
 30 inline void write(ll x)
 31 {
 32   if(x < 0) x = -x, putchar('-');
 33   if(x >= 10) write(x / 10);
 34   putchar(x % 10 + '0');
 35 }
 36 
 37 int n, m, t;
 38 struct Edge
 39 {
 40   int nxt, from, to, cap, flow;
 41 }e[maxn << 2];
 42 int head[maxn << 1], ecnt = 1;  //初值一定是奇数,否则^1不是他的反向边!
 43 void addEdge(int x, int y)
 44 {
 45   e[++ecnt] = (Edge){head[x], x, y, 1, 0};
 46   head[x] = ecnt;
 47   e[++ecnt] = (Edge){head[y], y, x, 0, 0};
 48   head[y] = ecnt;
 49 }
 50 
 51 int dis[maxn];
 52 bool bfs()
 53 {
 54   Mem(dis, 0); dis[0] = 1;
 55   queue<int> q; q.push(0);
 56   while(!q.empty())
 57     {
 58       int now = q.front(); q.pop();
 59       for(int i = head[now]; i; i = e[i].nxt)
 60       if(!dis[e[i].to] && e[i].cap > e[i].flow)
 61         {
 62           dis[e[i].to] = dis[now] + 1;
 63           q.push(e[i].to);
 64         }
 65     }
 66   return dis[t];
 67 }
 68 int cur[maxn];
 69 int dfs(int now, int res)
 70 {
 71   if(now == t || res == 0) return res;
 72   int flow = 0, f;
 73   if(!cur[now]) cur[now] = head[now];
 74   for(int &i = cur[now]; i; i = e[i].nxt)
 75     {
 76       if(dis[e[i].to] == dis[now] + 1 && (f = dfs(e[i].to, min(res, e[i].cap - e[i].flow))) > 0)
 77     {
 78       e[i].flow += f; e[i ^ 1].flow -= f;
 79       flow += f; res -= f;
 80       if(res == 0) break;
 81     }
 82     }
 83   return flow;
 84 }
 85 
 86 int maxflow()
 87 {
 88   int flow = 0;
 89   while(bfs())
 90     {
 91       Mem(cur, 0);
 92       flow += dfs(0, INF);
 93     }
 94   return flow;
 95 }
 96 
 97 void init()
 98 {
 99   Mem(head, 0); ecnt = 1;
100 }
101 
102 int main()
103 {
104   int T = read();
105   while(T--)
106     {
107       n = read(); m = read(); t = n + n + 1;
108       init();
109       for(int i = 1; i <= n; ++i) addEdge(0, i), addEdge(i + n, t);
110       for(int i = 1; i <= m; ++i)
111     {
112       int x = read(), y = read();
113       addEdge(x, y + n);
114     }
115       write(n - maxflow()); enter;
116     }
117   return 0;
118 }
View Code

 

posted @ 2018-10-18 18:00  mrclr  阅读(211)  评论(0编辑  收藏  举报