zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    模板 无源汇上下界可行流 loj115
    ICPC2018JiaozuoE Resistors in Parallel 高精度 数论
    hdu 2255 奔小康赚大钱 最佳匹配 KM算法
    ICPC2018Beijing 现场赛D Frog and Portal 构造
    codeforce 1175E Minimal Segment Cover ST表 倍增思想
    ICPC2018Jiaozuo 现场赛H Can You Solve the Harder Problem? 后缀数组 树上差分 ST表 口胡题解
    luogu P1966 火柴排队 树状数组 逆序对 离散化
    luogu P1970 花匠 贪心
    luogu P1967 货车运输 最大生成树 倍增LCA
    luogu P1315 观光公交 贪心
  • 原文地址:https://www.cnblogs.com/mrclr/p/9812784.html
Copyright © 2011-2022 走看看