算法问题实战策略 GALLERY

地址 https://algospot.com/judge/problem/read/GALLERY

 

 

 分析

如图 显然是需要在 0 1 2三个点进行监控即可。(0 2 3 也可)

根据题意,不存在回路,也就是不重复经过两画廊之间的走廊是不可能在两画廊之间进行走动的

我们可以将该图看成一棵树,深度优先遍历时,叶子结点的父节点需要放置摄像头,这样能将叶子结点 父节点和父节点的父节点均可监视到。然后根据有无未监视的子节点 决定当前节点的状态(需要放置,被监视,未被监视)

代码如下

 1 #include <iostream>
 2 #include <vector>
 3 
 4 
 5 using namespace std;
 6 
 7 const int N = 10010;
 8 int V;
 9 vector<int> adj[10010];
10 vector<bool> visited;
11 const int UNWATCHED = 0;
12 const int  WATCHED = 1;
13 const int INSTALLED = 2;
14 
15 int installed;
16 
17 int dfs(int here)
18 {
19     visited[here] = true;
20     int children[3] = { 0,0,0 };
21     for (int i = 0; i < adj[here].size(); i++)
22     {
23         int there = adj[here][i];
24         if (!visited[there])
25             ++children[dfs(there)];
26     }
27 
28     //后代节点存在没有监视的节点 在该节点安装摄像头
29     if (children[UNWATCHED]) {
30         ++installed;
31         return INSTALLED;
32     }
33 
34     if (children[INSTALLED]) {
35         return WATCHED;
36     }
37 
38     return UNWATCHED;
39 }
40 
41 int installCamera()
42 {
43     installed = 0;
44     visited = vector<bool>(V, false);
45     for (int u = 0; u < V; ++u) {
46         if (!visited[u] && dfs(u) == UNWATCHED)
47             ++installed;
48     }
49 
50     return installed;
51 }
52 
53 
54 
55 /*
56 3
57 6 5
58 0 1
59 1 2
60 1 3
61 2 5
62 0 4
63 4 2
64 0 1
65 2 3
66 1000 1
67 0 1
68 =====================
69 3
70 2
71 999
72 */
73 
74 int main()
75 {
76     int sampleCount = 0;
77     cin >> sampleCount;
78     while (sampleCount--) {
79         int n, m; visited.clear();
80         for (int i = 0; i < 10010; i++) adj[i].clear();
81         cin >> V >> m;
82         for (int i = 0; i < m; i++) {
83             int a, b;
84             cin >> a >> b;
85             adj[a].push_back(b); 
86             adj[b].push_back(a);
87         }
88         cout << installCamera() << endl;
89     }
90 
91     return 0;
92 }
View Code

 

posted on 2019-11-02 20:51  itdef  阅读(252)  评论(0编辑  收藏  举报

导航