zoukankan      html  css  js  c++  java
  • Poj 2594 Treasure Exploration (最小边覆盖+传递闭包)

    题目链接:

      Poj 2594 Treasure Exploration

    题目描述:

      在外星上有n个点需要机器人去探险,有m条单向路径。问至少需要几个机器人才能遍历完所有的点,一个点可以被多个机器人经过。

    解题思路:

      一眼看上去是普通的最小边覆盖,但是仔细想后发现如果在原图上进行最大匹配的话,每个点只能经过一次。这样的话对于本题求出的并不是最优解,所以我们要先对原图进行传递闭包处理,然后再进行最大匹配。

    这个题目点数太少H_K和匈牙利算法在空间和时间上并没有什么差,就代码复杂度而言匈牙利算法更有优势。

     1 #include <iostream>//匈牙利算法
     2 #include <cstring>
     3 #include <queue>
     4 #include <cmath>
     5 #include <cstdio>
     6 using namespace std;
     7 
     8 const int maxn = 510;
     9 int maps[maxn][maxn], n, m;
    10 int used[maxn], vis[maxn];
    11 void floyd ()
    12 {
    13     for (int k=1; k<=n; k++)
    14         for (int i=1; i<=n; i++)
    15             for (int j=1; j<=n; j++)
    16                 if (maps[i][k] && maps[k][j])
    17                     maps[i][j] = 1;
    18 }
    19 int Find (int u)
    20 {
    21     for (int i=1; i<=n; i++)
    22     {
    23         if (!vis[i] && maps[u][i])
    24         {
    25             vis[i] = 1;
    26             if (!used[i] || Find(used[i]))
    27             {
    28                 used[i] = u;
    29                 return 1;
    30             }
    31         }
    32     }
    33     return 0;
    34 }
    35 int main ()
    36 {
    37     while (scanf ("%d %d", &n, &m), n||m)
    38     {
    39         memset (maps, 0, sizeof(maps));
    40         while (m --)
    41         {
    42             int u, v;
    43             scanf ("%d %d", &u, &v);
    44             maps[u][v] = 1;
    45         }
    46         floyd ();
    47         memset (used, 0, sizeof(used));
    48         int res = 0;
    49         for (int i=1; i<=n; i++)
    50         {
    51             memset (vis, 0, sizeof(vis));
    52             res += Find(i);
    53         }
    54         printf ("%d
    ", n - res);
    55     }
    56     return 0;
    57 }
      1 #include <iostream>//H_K算法
      2 #include <cstring>
      3 #include <queue>
      4 #include <cmath>
      5 #include <cstdio>
      6 using namespace std;
      7 
      8 const int maxn = 510;
      9 const int INF = 0x3f3f3f3f;
     10 int maps[maxn][maxn], n, m, dx[maxn], dy[maxn];
     11 int vis[maxn], cx[maxn], cy[maxn], dis;
     12 void floyd ()
     13 {
     14     for (int k=1; k<=n; k++)
     15         for (int i=1; i<=n; i++)
     16             for (int j=1; j<=n; j++)
     17                 if (maps[i][k] && maps[k][j])
     18                     maps[i][j] = 1;
     19 }
     20 bool bfs ()
     21 {
     22     queue <int> Q;
     23     dis = INF;
     24     memset (dx, -1, sizeof(dx));
     25     memset (dy, -1, sizeof(dy));
     26     for (int i=1; i<=n; i++)
     27         if (cx[i] == -1)
     28             {
     29                 Q.push(i);
     30                 dx[i] = 0;
     31             }
     32     while (!Q.empty())
     33     {
     34         int u = Q.front();
     35         Q.pop();
     36         if (dx[u] > dis)
     37             break;
     38         for (int i=1; i<=n; i++)
     39         {
     40             if (dy[i]==-1 && maps[u][i])
     41             {
     42                 dy[i] = dx[u] + 1;
     43                 if (cy[i] == -1)
     44                     dis = dy[i];
     45                 else
     46                 {
     47                     dx[cy[i]] = dy[i] +1;
     48                     Q.push (cy[i]);
     49                 }
     50             }
     51         }
     52     }
     53     return dis != INF;
     54 }
     55 int dfs (int u)
     56 {
     57     for (int v=1; v<=n; v++)
     58     {
     59         if (!vis[v] && dx[u]+1==dy[v] && maps[u][v])
     60         {
     61             vis[v] = 1;
     62             if (cy[v]!=-1 && dis==dy[v])
     63                 continue;
     64             if (cy[v]==-1 || dfs(cy[v]))
     65             {
     66                 cx[u] = v;
     67                 cy[v] = u;
     68                 return 1;
     69             }
     70         }
     71     }
     72     return 0;
     73 }
     74 int Max_match ()
     75 {
     76     int res = 0;
     77     memset (cx, -1, sizeof(cx));
     78     memset (cy, -1, sizeof(cy));
     79     while (bfs())
     80     {
     81         memset (vis, 0, sizeof(vis));
     82         for (int i=1; i<=n; i++)
     83             if (cx[i] == -1)
     84                 res += dfs (i);
     85     }
     86     return res;
     87 }
     88 int main ()
     89 {
     90     while (scanf ("%d %d", &n, &m), n||m)
     91     {
     92         memset (maps, 0, sizeof(maps));
     93         while (m --)
     94         {
     95             int u, v;
     96             scanf ("%d %d", &u, &v);
     97             maps[u][v] = 1;
     98         }
     99         floyd ();
    100         printf ("%d
    ", n - Max_match());
    101     }
    102     return 0;
    103 }
    本文为博主原创文章,未经博主允许不得转载。
  • 相关阅读:
    Python
    QinQ 技术解析
    TLS/SSL 协议
    TLS/SSL 协议
    TLS/SSL 协议
    排序算法之基本排序算法(冒泡、插入、选择)
    Spring Boot 学习笔记--手写版
    mysql -- collection一对多查询
    mybatis 批量操作增删改查
    easyUI之datagrid绑定后端返回数据的两种方式
  • 原文地址:https://www.cnblogs.com/alihenaixiao/p/4701117.html
Copyright © 2011-2022 走看看