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 }
  • 相关阅读:
    Java 第十一届 蓝桥杯 省模拟赛 梅花桩
    Java 第十一届 蓝桥杯 省模拟赛 梅花桩
    Java 第十一届 蓝桥杯 省模拟赛 梅花桩
    Java 第十一届 蓝桥杯 省模拟赛 元音字母辅音字母的数量
    Java 第十一届 蓝桥杯 省模拟赛 元音字母辅音字母的数量
    Java 第十一届 蓝桥杯 省模拟赛 元音字母辅音字母的数量
    Java 第十一届 蓝桥杯 省模拟赛 最大的元素距离
    Java 第十一届 蓝桥杯 省模拟赛 递增序列
    Java 第十一届 蓝桥杯 省模拟赛 递增序列
    Java 第十一届 蓝桥杯 省模拟赛 最大的元素距离
  • 原文地址:https://www.cnblogs.com/shijianming/p/4140803.html
Copyright © 2011-2022 走看看