zoukankan      html  css  js  c++  java
  • [POJ3041]Asteroids(二分图,最大匹配)

    题目链接:http://poj.org/problem?id=3041

    题意:N*N中选最少行或者列,可以覆盖所有的点。

    最小点覆盖问题,等于最大匹配。

    建图:考虑行,选中某一行,那么行上的点对应的列则不需要被选。根据这一条,建图就行。

     1 #include <algorithm>
     2 #include <iostream>
     3 #include <iomanip>
     4 #include <cstring>
     5 #include <climits>
     6 #include <complex>
     7 #include <cassert>
     8 #include <cstdio>
     9 #include <bitset>
    10 #include <vector>
    11 #include <deque>
    12 #include <queue>
    13 #include <stack>
    14 #include <ctime>
    15 #include <set>
    16 #include <map>
    17 #include <cmath>
    18 using namespace std;
    19 
    20 typedef pair<int, int> pii;
    21 const int maxn = 1050;
    22 const int inf = 0x3f3f3f3f;
    23 int n, k;
    24 int G[maxn][maxn];
    25 int nx,ny;
    26 int linker[maxn],lx[maxn],ly[maxn];
    27 int slack[maxn];
    28 bool visx[maxn],visy[maxn];
    29 
    30 bool dfs(int x) {
    31     visx[x] = true;
    32     for(int y = 0; y < ny; y++) {
    33         if(visy[y])continue;
    34         int tmp = lx[x] + ly[y] - G[x][y];
    35         if(tmp == 0) {
    36             visy[y] = true;
    37             if(linker[y] == -1 || dfs(linker[y])) {
    38                 linker[y] = x;
    39                 return true;
    40             }
    41         }
    42         else if(slack[y] > tmp)
    43             slack[y] = tmp;
    44     }
    45     return false;
    46 }
    47 
    48 int km() {
    49     memset(linker,-1,sizeof(linker));
    50     memset(ly,0,sizeof(ly));
    51     for(int i = 0;i < nx;i++) {
    52         lx[i] = -inf;
    53         for(int j = 0;j < ny;j++)
    54             if(G[i][j] > lx[i])
    55                 lx[i] = G[i][j];
    56     }
    57     for(int x = 0;x < nx;x++) {
    58         for(int i = 0;i < ny;i++)
    59             slack[i] = inf;
    60         while(true) {
    61             memset(visx,false,sizeof(visx));
    62             memset(visy,false,sizeof(visy));
    63             if(dfs(x))break;
    64             int d = inf;
    65             for(int i = 0;i < ny;i++)
    66                 if(!visy[i] && d > slack[i])
    67                     d = slack[i];
    68             for(int i = 0;i < nx;i++)
    69                 if(visx[i])
    70                     lx[i] -= d;
    71             for(int i = 0;i < ny;i++) {
    72                 if(visy[i])ly[i] += d;
    73                 else slack[i] -= d;
    74             }
    75         }
    76     }
    77     int res = 0;
    78     for(int i = 0;i < ny;i++)
    79         if(linker[i] != -1)
    80             res += G[linker[i]][i];
    81     return res;
    82 }
    83 
    84 int main() {
    85     // freopen("in", "r", stdin);
    86     int x, y;
    87     while(~scanf("%d%d",&n,&k)) {
    88         memset(G, 0, sizeof(G));
    89         for(int i = 1; i <= k; i++) {
    90             scanf("%d%d",&x,&y);
    91             G[x-1][y-1]++;
    92         }
    93         nx = n, ny = n;
    94         printf("%d
    ", km());
    95     }
    96     return 0;
    97 }
  • 相关阅读:
    Volley学习(RequestQueue分析)
    Volley学习(Volly分析)
    AsyncTask学习
    如何排放表单标签介绍的位置?
    了解hr标签的各种浏览器兼容问题
    多屏移动端网站开发需要注意的十大技巧
    让吃货垂涎三尺的美食酷站!—— 每周酷站欣赏 #1
    12个响应式导航菜单jQuery插件,让您轻松应对响应式网站!
    网页设计师必看!27个响应式的简约风格网站
    网页设计师必看!12个漂亮颜色搭配的国外网站欣赏
  • 原文地址:https://www.cnblogs.com/kirai/p/6774001.html
Copyright © 2011-2022 走看看