地址 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 }