ZOJ 3811 Untrusted Patrol dfs

Untrusted Patrol

Time Limit: 3 Seconds      Memory Limit: 65536 KB

Edward is a rich man. He owns a large factory for health drink production. As a matter of course, there is a large warehouse in the factory.

To ensure the safety of drinks, Edward hired a security man to patrol the warehouse. The warehouse has N piles of drinks and M passageways connected them (warehouse is not big enough). When the evening comes, the security man will start to patrol the warehouse following a path to check all piles of drinks.

Unfortunately, Edward is a suspicious man, so he sets sensors on K piles of the drinks. When the security man comes to check the drinks, the sensor will record a message. Because of the memory limit, the sensors can only record for the first time of the security man's visit.

After a peaceful evening, Edward gathered all messages ordered by recording time. He wants to know whether is possible that the security man has checked all piles of drinks. Can you help him?

The security man may start to patrol at any piles of drinks. It is guaranteed that the sensors work properly. However, Edward thinks the security man may not works as expected. For example, he may digs through walls, climb over piles, use some black magic to teleport to anywhere and so on.

Input

There are multiple test cases. The first line of input is an integer T indicates the number of test cases. For each test case:

The first line contains three integers N (1 <= N <= 100000), M (1 <= M <= 200000) and K (1 <= K <= N).

The next line contains K distinct integers indicating the indexes of piles (1-based) that have sensors installed. The following M lines, each line contains two integers Ai and Bi (1 <= AiBi <= N) which indicates a bidirectional passageway connects piles Ai and Bi.

Then, there is an integer L (1 <= L <= K) indicating the number of messages gathered from all sensors. The next line contains L distinct integers. These are the indexes of piles where the messages came from (each is among the K integers above), ordered by recording time.

Output

For each test case, output "Yes" if the security man worked normally and has checked all piles of drinks, or "No" if not.

Sample Input

2
5 5 3
1 2 4
1 2
2 3
3 1
1 4
4 5
3
4 2 1
5 5 3
1 2 4
1 2
2 3
3 1
1 4
4 5
3
4 1 2

Sample Output

No
Yes

Author: DAI, Longao
Source: The 2014 ACM-ICPC Asia Mudanjiang Regional First Round

 

今天做的网络赛,真是简直了,我来总结下这道题目所犯的一系列错误,做这道题目做的好曲折啊。

1.刚开始以为是割点,看了一会,不知道怎么在搜索的过程中判断如果当前节点是割点的话,儿子节点是不是已经访问过了,直到我自己找到了一种割点的反例,就是一种环,哭瞎了。

2.后来的思路和正解有点相近了,就是先把序列的点都标记下来,不能访问。然后,我是这样想的,就是在序列中两两之间找路径,正解也确实是这个思路,但是在确定这个路径的时候,我只想到了这两个点之间做一个dfs,,这样必超时。

3.这样想着想着就到了5点多,最终在网络赛期间也没有做出来。

4.看到了同学是一个一个点的拓展成一个区域,序列中下个点如果拓展的点和这个区域有重合的那么就说明有一条路径,啊啊啊啊啊啊啊,我当时咋没有想到,所以这样来说并查集也是可以做的。

5细节问题:l<k 一定是NO,图不连通的话一定是NO。

 

 代码一 并查集

————————————————————————————————————哭瞎——————————————————————————-——————————————-

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<string>
  5 #include<map>
  6 #include<set>
  7 #include<cmath>
  8 #include<stack>
  9 #include<queue>
 10 #include<vector>
 11 #include<algorithm>
 12 #include<sstream>
 13 #define inf 0x3f3f3f3f
 14 #define PI acos(-1.0)
 15 #define eps 1e-6
 16 #define LL long long
 17 #define MEM(a,b) memset(a,b,sizeof(a))
 18 #define PB push_back
 19 #define IN freopen("in.txt","r",stdin);
 20 #define OUT freopen("out.txt","w",stdout);
 21 #define BUG printf("bug************bug************bug\n");
 22 
 23 using namespace std;
 24 
 25 const int N=100010;
 26 vector <int>G[N];
 27 bool use[N],visit[N];
 28 int q[N],f[N];
 29 bool flag;
 30 
 31 int Find(int u)
 32 {
 33     if (f[u]!=u)
 34         f[u]=Find(f[u]);
 35     return f[u];
 36 }
 37 
 38 bool Union(int u,int v)
 39 {
 40     int fa1=Find(u);
 41     int fa2=Find(v);
 42     f[fa2]=fa1;
 43     return fa1==fa2;
 44 }
 45 
 46 void dfs(int u)
 47 {
 48     for (int i=0;i<G[u].size();i++){
 49         int v=G[u][i];
 50         if (use[v]){
 51             if (!Union(u,v))
 52                 dfs(v);
 53         }
 54     }
 55 }
 56 
 57 int main()
 58 {
 59     int T,n,m,k,u,v,l,fa1,fa2;
 60     bool ans;
 61     scanf("%d",&T);
 62     while (T--){
 63         MEM(use,true);
 64         scanf("%d%d%d",&n,&m,&k);
 65         for (int i=1;i<=n;i++){
 66             G[i].clear();
 67             f[i]=i;
 68         }
 69         for (int i=1;i<=k;i++){
 70             scanf("%d",&v);
 71             use[v]=false;
 72         }
 73         for (int i=1;i<=m;i++){
 74             scanf("%d%d",&u,&v);
 75             G[u].push_back(v);
 76             G[v].push_back(u);
 77         }
 78         scanf("%d",&l);
 79         for (int i=1;i<=l;i++)
 80                 scanf("%d",&q[i]);
 81         if (l<k){
 82             printf("No\n");
 83         }
 84         else{
 85             dfs(q[1]);
 86             use[q[1]]=true;
 87             ans=true;
 88             for (int i=2;i<=l;i++){
 89                 dfs(q[i]);
 90                 use[q[i]]=true;
 91                 fa1=Find(q[i-1]);
 92                 fa2=Find(q[i]);
 93                 if (fa1!=fa2){
 94                     ans=false;
 95                     break;
 96                 }
 97             }
 98             for (int i=1;i<=n;i++)
 99                 Find(i);
100             for (int i=2;i<=n;i++)
101                 if (f[i]!=f[1])
102                     ans=false;
103             if (ans)
104                 printf("Yes\n");
105             else
106                 printf("No\n");
107         }
108     }
109     return 0;
110 }

 代码二 类似floodfill

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<map>
#include<set>
#include<cmath>
#include<stack>
#include<queue>
#include<vector>
#include<algorithm>
#include<sstream>
#define inf 0x3f3f3f3f
#define PI acos(-1.0)
#define eps 1e-6
#define LL long long
#define MEM(a,b) memset(a,b,sizeof(a))
#define PB push_back
#define IN freopen("in.txt","r",stdin);
#define OUT freopen("out.txt","w",stdout);
#define BUG printf("bug************bug************bug\n");

using namespace std;

const int N=100010;
vector <int>G[N];
bool use[N],visit[N];
int q[N];
bool flag;

void dfs(int u)
{
    for (int i=0;i<G[u].size();i++){
        int v=G[u][i];
        if (visit[v]){
            flag=true;
            continue;
        }
        else{
            if (!use[v])
                continue;
            use[v]=false;
            dfs(v);
            visit[v]=true;
        }
    }
}

int main()
{
    int T,n,m,k,u,v,l;
    bool ans;
    scanf("%d",&T);
    while (T--){
        MEM(use,true);
        MEM(visit,false);
        scanf("%d%d%d",&n,&m,&k);
        for (int i=1;i<=n;i++)
            G[i].clear();
        for (int i=1;i<=k;i++){
            scanf("%d",&v);
            use[v]=false;
        }
        for (int i=1;i<=m;i++){
            scanf("%d%d",&u,&v);
            G[u].push_back(v);
            G[v].push_back(u);
        }
        scanf("%d",&l);
        for (int i=1;i<=l;i++)
                scanf("%d",&q[i]);
        if (l<k){
            printf("No\n");
        }
        else{
            dfs(q[1]);
            visit[q[1]]=true;
            ans=true;
            for (int i=2;i<=l;i++){
                flag=false;
                dfs(q[i]);
                visit[q[i]]=true;
                if (!flag){
                    ans=false;
                    break;
                }
            }
            for (int i=1;i<=n;i++)
                if (!visit[i])
                    ans=false;
            if (ans)
                printf("Yes\n");
            else
                printf("No\n");
        }
    }
    return 0;
}

 

posted on 2014-09-07 20:43  wzb_hust  阅读(569)  评论(0编辑  收藏  举报

导航