• UVA 12549


    题意:给定一个Y行X列的网格,网格种有重要位置和障碍物。要求用最少的机器人看守所有重要的位置,每个机器人放在一个格子里,面朝上下左右四个方向之一发出激光直到射到障碍物为止,沿途都是看守范围。机器人不会阻挡射线。

    “#”表示障碍物,“*”表示重要的位置,箭头表示最终机器人匹配的位置,求出机器人能够匹配出的最少位置个数。

    分析:首先看题解是二分图匹配,但是建图目前还没想到呢。每个机器人绝对都在重要位置上,假设每个重要位置上都有机器人,可以保护哪几个重要物品。看是否能够匹配得来

      1 #include<cstdio>
      2 #include<memory.h>
      3 #include <iostream>
      4 using namespace std;
      5 #define repu(i, a, b) for(int i = (a); i < (b); i++)
      6 #define MAX 202
      7 bool flag,visit[MAX];    ///记录V2中的某个点是否被搜索过
      8 int match[MAX];   ///记录与V2中的点匹配的点的编号
      9 int cow, stall;   ///二分图中左边、右边集合中顶点的数目
     10 int head[MAX];
     11 struct edge
     12 {
     13     int to,next;
     14 } e[10005];
     15 int index,X,Y;
     16 void addedge(int u,int v)
     17 {
     18     ///向图中加边的算法,注意加上的是有向边
     19     ///u为v的后续节点既是v---->u
     20     e[index].to=v;
     21     e[index].next=head[u];
     22     head[u]=index;
     23     index++;
     24 }
     25 /// 匈牙利(邻接表)算法
     26 bool dfs(int u)
     27 {
     28     int i,v;
     29     for(i = head[u]; i != 0; i = e[i].next)
     30     {
     31         v = e[i].to;
     32         if(!visit[v])   ///如果节点v与u相邻并且未被查找过
     33         {
     34             visit[v] = true;   ///标记v为已查找过
     35             if(match[v] == -1 || dfs(match[v]))   ///如果i未在前一个匹配M中,或者i在匹配M中,但是从与i相邻的节点出发可以有增广路径
     36             {
     37                 match[v] = u;  ///记录查找成功记录,更新匹配M(即“取反”)
     38                 return true;   ///返回查找成功
     39             }
     40         }
     41     }
     42     return false;
     43 }
     44 int g[MAX][MAX];
     45 pair<int, int> Map[MAX][MAX];
     46 int n,m;
     47 void MaxMatch()
     48 {
     49     int i,sum=0;
     50     memset(match,-1,sizeof(match));
     51     for(i = 0; i < X; ++i)
     52     {
     53         memset(visit,false,sizeof(visit));///清空上次搜索时的标记
     54         if(dfs(i))    ///从节点i尝试扩展
     55             sum++;
     56     }
     57     printf("%d
    ",sum);
     58 }
     59 void build()
     60 {
     61     int r = -1, c = -1;
     62     repu(i,1,n+1)
     63     {
     64         bool flag = true;
     65         repu(j,1,m+1)
     66         {
     67             if(g[i][j] == 1)
     68             {
     69                 ///如果没有障碍物,说明一个机器人就可以解决,否则就得加一个机器人
     70                 if(flag)
     71                     ++r;
     72                 Map[i][j].first = r;
     73                 flag = false;
     74             }
     75             if(g[i][j] == 2)
     76                 flag = true;
     77         }
     78     }
     79     repu(j,1,m+1)
     80     {
     81         bool flag = true;
     82         repu(i,1,n+1)
     83         {
     84             if(g[i][j] == 1)
     85             {
     86                 if(flag) ++c;
     87                 Map[i][j].second = c;
     88                 flag = false;
     89             }
     90             if(g[i][j] == 2) flag = true;
     91         }
     92     }
     93     X = r + 1;
     94     repu(i,1,n+1)
     95     repu(j,1,m+1)
     96     if(g[i][j] == 1)
     97     {
     98         addedge(Map[i][j].first,Map[i][j].second);
     99         cout<<Map[i][j].first<<"--"<<Map[i][j].second<<endl;
    100     }
    101 }
    102 void init()
    103 {
    104     int a, x, y;
    105     memset(g, 0, sizeof(g));
    106     scanf("%d%d%d", &n, &m, &a);
    107     while(a--)
    108     {
    109         scanf("%d%d", &x, &y);
    110         g[x][y] = 1;
    111     }
    112     scanf("%d", &a);
    113     while(a--)
    114     {
    115         scanf("%d%d", &x, &y);
    116         g[x][y] = 2;
    117     }
    118 }
    119 ///和POJ 3041的区别就是有障碍物
    120 ///因为有障碍物,所以需要进行行列拆分。。。即build
    121 int main()
    122 {
    123     int T,a,b,x,y,l,r;
    124     scanf("%d",&T);
    125     while(T--)
    126     {
    127         memset(head,0,sizeof(head));    ///切记要初始化
    128         index = 1;
    129         init();
    130         build();
    131         MaxMatch();
    132     }
    133     return 0;
    134 }
    View Code

     

  • 相关阅读:
    linux设置系统变量
    linux通配符
    linux 别名
    echo 输出颜色
    Linux:echo命令详解
    poj 2456 Aggressive cows 二分 题解《挑战程序设计竞赛》
    poj 1064 Cable master 二分 题解《挑战程序设计竞赛》
    染色法判定二分图 模板 题解《挑战程序设计竞赛》
    poj 1182 食物链 并查集 题解《挑战程序设计竞赛》
    poj 2431 Expedition 贪心 优先队列 题解《挑战程序设计竞赛》
  • 原文地址:https://www.cnblogs.com/ACMERY/p/4779770.html
Copyright © 2020-2023  润新知