Untrusted Patrol 14牡丹江网络赛C

10 篇文章 0 订阅
题意:给定一个n个点,m条边的图,其中k个点上有探测器

再给定一个探测器第一次被遍历的序列,问是否存在一种遍历顺序使得满足给定序列且遍历完所有点


思路:从第一个被遍历的探测器开始dfs,每次访问到探测器遍停止,访问到非探测器节点便搜下去。结束后判断给定序列下个探测 器是否被访问过,若没有,说明无法不通过 其他 探测器到达此探测器,无解。若被访问过,继续dfs此结点。

这样dfs到的探测器保证了是从当前结点可以不通过任何探测器结点便可以访问的,最后判断一下是否每个节点都被访问过,即 图是否连通


//#include <bits/stdc++.h>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <cmath>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;

//LOOP
#define FF(i, a, b) for(int i = (a); i < (b); ++i)
#define FE(i, a, b) for(int i = (a); i <= (b); ++i)
#define FED(i, b, a) for(int i = (b); i>= (a); --i)
#define REP(i, N) for(int i = 0; i < (N); ++i)
#define CLR(A,value) memset(A,value,sizeof(A))
#define FC(it, c) for(__typeof((c).begin()) it = (c).begin(); it != (c).end(); it++)

#define PB push_back

//INPUT
#define RI(n) scanf("%d", &n)
#define RII(n, m) scanf("%d%d", &n, &m)
#define RIII(n, m, k) scanf("%d%d%d", &n, &m, &k)
#define RIV(n, m, k, p) scanf("%d%d%d%d", &n, &m, &k, &p)

#define sqr(x) (x) * (x)
typedef long long LL;
typedef unsigned long long ULL;
typedef vector <int> VI;
const int INF = 0x3f3f3f3f;
const LL lINF = 0x3f3f3f3f3f3f3f3fLL;
const double eps = 1e-9;
const int MOD = 1e9 + 7;
const double PI = acos(-1.0);
const int maxn = 100010;

int n, m, k;
bool is[maxn], vis[maxn];
VI G[maxn], K;

void init()
{
    CLR(is, 0);
    CLR(vis, 0);
    K.clear();
    FE(i, 0, n + 1) G[i].clear();
}

void dfs(int u)
{
    vis[u] = 1;
    REP(i, G[u].size())
    {
        int v = G[u][i];
        if (vis[v]) continue;
        if (is[v])
        {
            vis[v] = 1;
            continue;
        }
        else
            dfs(v);
    }
}

int main()
{
    int T, x, y;
    RI(T);
    while (T--)
    {
        RIII(n, m, k);
        init();
        REP(i, k)
        {
            RI(x);
            is[x] = 1;
        }
        REP(i, m)
        {
            RII(x, y);
            G[x].PB(y), G[y].PB(x);
        }
        int L, flag = 1;
        RI(L);
        REP(i, L)
        {
            RI(x);
            K.PB(x);
        }
        if (L < k)
        {
            flag = 0;
            goto end;
        }
        dfs(K[0]);
        FF(i, 1, K.size())
        {
            if (vis[K[i]])
                dfs(K[i]);
            else
            {
                flag = 0;
                goto end;
            }
        }
        FE(i, 1, n)
            if (!vis[i])
            {
                flag = 0;
                break;
            }
        end:;
        if (flag)
            puts("Yes");
        else
            puts("No");
    }
    return 0;
}
/*
*/


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值