zoukankan      html  css  js  c++  java
  • POJ3041Asteroids【最小点覆盖】

    大意:

    X.X 
    .X. 
    .X.
         如左图X代表怪物你可以用激光去消灭它们,一次可以消灭同一行或同一列的所有怪物,问最少多少次才可以把所有怪物消灭完

    思路:把x,y坐标分别看成左集合与右集合,若两个坐标有联系就建一条边

    最后求得是最小点覆盖

    正确性证明:每个怪物的坐标都是由一对x,y确定的,在二分图中每条边就代表一对坐标点,所以只要把所有的边被覆盖就可以了

    代码:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 #include <set>
     6 using namespace std;
     7 
     8 const int maxn = 505;
     9 
    10 struct Node {
    11     int to, next;
    12 }p[10005];
    13 
    14 int head[10005];
    15 
    16 int tot;
    17 
    18 int X[maxn];
    19 int x_cnt;
    20 int vis[maxn];
    21 int link[maxn];
    22 
    23 void AddEdge(int u, int v) {
    24     p[tot].to = v;
    25     p[tot].next = head[u];
    26     head[u] = tot ++;
    27 }
    28 
    29 bool Find(int u) {
    30     for(int i = head[u]; i; i = p[i].next) {
    31         int v = p[i].to;
    32         if(!vis[v]) {
    33             vis[v] = 1;
    34             if(link[v] == -1 || Find(link[v])) {
    35                 link[v] = u;
    36                 return true;
    37             }
    38         }
    39     }
    40     return false;
    41 }
    42 int n;
    43 
    44 int solve() {
    45     int cnt = 0;
    46     memset(link, -1, sizeof(link));
    47     memset(vis, 0, sizeof(vis));
    48     if(Find(X[0])) cnt++;
    49     for(int i = 1; i < x_cnt; i++) {
    50         if(X[i] == X[i - 1]) continue;
    51         memset(vis, 0, sizeof(vis));
    52         if(Find(X[i])) cnt++;
    53     }
    54     return cnt;
    55 }
    56 
    57 int main() {
    58     int k;
    59     int u, v;
    60     //freopen("3041.txt","r",stdin);
    61     while(EOF != scanf("%d %d",&n, &k)) {
    62         tot = 1;
    63         x_cnt = 0;
    64         memset(head, 0, sizeof(head));
    65         //memset(X, 0, sizeof(X));
    66         for(int i = 0; i < k; i++) {
    67             scanf("%d %d",&u, &v);
    68             AddEdge(u, v);
    69             X[x_cnt++] = u;
    70         }
    71         sort(X, X + x_cnt);
    72         printf("%d
    ",solve());
    73     }
    74     return 0;
    75 }
    View Code
  • 相关阅读:
    产生WM_PAINT 消息
    模板作为模板的参数
    转:网络游戏同步原理荟萃
    一个隐晦的c++语法问题
    Winbind authentication against active directory
    In Place Upgrade of CentOS 6 to CentOS 7
    How To mount/Browse Windows Shares【在linux{centos}上挂载、浏览window共享】
    File System Shell
    Administration Commands
    User Commands
  • 原文地址:https://www.cnblogs.com/zhanzhao/p/3900333.html
Copyright © 2011-2022 走看看