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", 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", n - Max_match());
101     }
102     return 0;
103 }

 

posted @ 2015-08-04 09:42  罗茜  阅读(183)  评论(0编辑  收藏  举报