zoukankan      html  css  js  c++  java
  • 并查集 + Bfs 之 zoj 3811 Untrusted Patrol

    //  [9/12/2014 Sjm]
    /*
    此题在大神的帮助下AC了。。。
    要求:output "Yes" if the security man worked normally and has checked all piles of drinks, or "No" if not.
    (1)check all piles of drinks: 
    	1) L == K (L 是 gathered from all sensors,所以若L < K,则必然是有些带有传感器的节点没有走,无法满足条件)
    	2) 图一定是连通,否则从一个点出发无法走遍所有节点 (通过并查集判断)
    (2)worked normally:
    	意思巡逻的路线是可以根据图中所给的边找出来的,
    	而不是digs through walls, climb over piles, use some black magic to teleport to anywhere and so on.
    	故而需要判断能否找到一个正常的巡逻路线。。。
    	( 注意正常的巡逻路线是可以重复走途中所给的边,
    	   即若A与B相连,A与C相连,则如果从A到B后,亦可从B返回A,再到C)
    	思路:
    	1)从第 K 个传感器所记录的点出发,寻找到其所有能到达的传感器所记录的点。。转向 2)
    	2)判断第 K+1 个传感器所记录的点,是否可由前K个传感器所记录的点所到达
    		若否,则即可判断正常的巡逻路线不存在。。。
    		若是,则 K = K + 1,不断进行操作 2),直至所有传感器的点均可被到达,可判断正常的巡逻路线存在。。。
    	关键:
    	如何用计算机去求 “从第 K 个传感器所记录的点出发,寻找到其所有能到达的传感器所记录的点”?
    	解法就像是自动机:
    		假设从点 A (此点即队列中第一个点)出发,采用 Bfs 找出该点能到达的所有点,
    		在这些点中,对于传感器记录的点进行标记,而对于非传感器记录的点,放到队列中,
    		再将队列中的点取出,继续寻找其能到达的所有点,同点 A 进行的操作处理。。
    		直到队列为空,则说明此时对于点 A 能到达的传感器记录的点都已标记下来。。。
    */
      1 #include <iostream>
      2 #include <cstdlib>
      3 #include <cstdio>
      4 #include <vector>
      5 #include <queue>
      6 using namespace std;
      7 const int MAX_N = 100005;
      8 int N, M, K;
      9 vector<int> Edge[MAX_N];
     10 bool isVis[MAX_N];
     11 bool isIn[MAX_N];
     12 int verOrder[MAX_N];
     13 int father[MAX_N];
     14 
     15 void Del() {
     16     for (int i = 1; i <= N; ++i) {
     17         if (!Edge[i].empty()) {
     18             Edge[i].clear();
     19         }
     20     }
     21 }
     22 
     23 int myFind(int x) {
     24     if (x == father[x]) return x;
     25     else return father[x] = myFind(father[x]);
     26 }
     27 
     28 bool judge_Connected_Graph() {
     29     int ver = myFind(N);
     30     for (int i = 1; i < N; ++i) {
     31         if (myFind(i) != ver) {
     32             return false;
     33         }
     34     }
     35     return true;
     36 }
     37 
     38 bool Bfs() {
     39     isVis[verOrder[0]] = true;
     40     queue<int> que;
     41     for (int i = 0; i < K; ++i) {
     42         if (isVis[verOrder[i]]) que.push(verOrder[i]);
     43         else return false;
     44         while (!que.empty()) {
     45             int ver = que.front();
     46             que.pop();
     47             for (int i = 0; i < Edge[ver].size(); ++i) {
     48                 int t_ver = Edge[ver][i];
     49                 if (!isVis[t_ver]) {
     50                     if (isIn[t_ver]) isVis[t_ver] = true;
     51                     else {
     52                         isVis[t_ver] = true;
     53                         que.push(t_ver);
     54                     }
     55                 }
     56             }
     57         }
     58     }
     59     return true;
     60 }
     61 
     62 int main() {
     63     //freopen("input.txt", "r", stdin);
     64     int T;
     65     scanf("%d", &T);
     66     while (T--) {
     67         scanf("%d %d %d", &N, &M, &K);
     68         for (int i = 1; i <= N; ++i) {
     69             isIn[i] = false;
     70             isVis[i] = false;
     71             father[i] = i;
     72         }
     73         int sensor;
     74         for (int i = 0; i < K; ++i) {
     75             scanf("%d", &sensor);
     76             isIn[sensor] = true;
     77         }
     78         int u, v;
     79         for (int i = 0; i < M; ++i) {
     80             scanf("%d %d", &u, &v);
     81             Edge[u].push_back(v);
     82             Edge[v].push_back(u);
     83             int tmp1 = myFind(v);
     84             int tmp2 = myFind(u);
     85             if (tmp1 != tmp2) {
     86                 father[tmp1] = tmp2;
     87             }
     88         }
     89         int sum;
     90         scanf("%d", &sum);
     91         for (int i = 0; i < sum; ++i) {
     92             scanf("%d", &sensor);
     93             verOrder[i] = sensor;
     94         }
     95         if ((sum < K) || (!judge_Connected_Graph()) || (!Bfs())) {
     96             printf("No
    ");
     97         }
     98         else printf("Yes
    ");
     99         Del();
    100     }
    101     return 0;
    102 }
  • 相关阅读:
    js上传图片预览
    Android 调用QQ登录
    未开启HugePages ORACLE session剧增时引起的一次悲剧
    脱了裤子放屁之std::string
    [Python爬虫] Selenium自己主动訪问Firefox和Chrome并实现搜索截图
    tomcat启动报错,找不到相应的 queue,从而引发内存泄漏
    LeetCode: Binary Tree Postorder Traversal [145]
    素数打表法。
    linux 抓包 tcpdump 简单应用
    Linux命令之kill
  • 原文地址:https://www.cnblogs.com/shijianming/p/4140803.html
Copyright © 2011-2022 走看看