POJ3041 Asteroids

嘟嘟嘟

 

最小覆盖数板子题。

每一行看成一个点,每一列也看成一个点,如果(x, y)有障碍,就从点x向y连一条边,这样就构成了一个二分图。然后求最小覆盖数,跑最大匹配。

求最小覆盖数是因为对于这条边连接的连个点,选择任意一个就行,所以求最小覆盖数。

  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 maxe = 2e4 + 5;
 21 const int maxn = 1e3 + 5;
 22 inline ll read()
 23 {
 24   ll ans = 0;
 25   char ch = getchar(), last = ' ';
 26   while(!isdigit(ch)) {last = ch; ch = getchar();}
 27   while(isdigit(ch)) {ans = ans * 10 + ch - '0'; ch = getchar();}
 28   if(last == '-') ans = -ans;
 29   return ans;
 30 }
 31 inline void write(ll x)
 32 {
 33   if(x < 0) x = -x, putchar('-');
 34   if(x >= 10) write(x / 10);
 35   putchar(x % 10 + '0');
 36 }
 37 int n, t, k;
 38 struct Edge
 39 {
 40   int nxt, from, to, cap, flow;
 41 }e[maxe];
 42 int head[maxn], ecnt = 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 int main()
 98 {
 99   n = read(); k = read(); t = n + n + 1;
100   for(int i = 1; i <= n; ++i) addEdge(0, i), addEdge(i + n, t);
101   for(int i = 1; i <= k; ++i)
102     {
103       int x = read(), y = read();
104       addEdge(x, y + n);
105     }
106   write(maxflow()), enter;
107   return 0;
108 }
View Code

 

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