您的位置:首页 > 其它

ZOJ Problem Set - 3811 Untrusted Patrol

2015-08-02 10:01 302 查看
题意: 给定一个图和若干放置了传感器的点,问能否遍历图并按照给定的顺序访问传感器 。

显然,我们一要判断图的连通性,二要判断是否按照所给顺序访问传感器 。

其实用dfs捎带着就可以判断了连通性,不用再另写并查集, 重点是怎么判断顺序 : 我们不妨按照顺序来依次DFS, 如果遇到传感器,那么就返回,不再搜索并将该点置零,这样,如果搜索到的这个传感器是下一个传感器,那么下一次dfs的传感器应该已经标记为0 。注意,由于传感器只记录第一次到达的时间,所以可以重复经过一个已经走过的传感器,因此这个方法才是对的 。 另外根据题意, k和l 必须是相等的 。

#include<bits/stdc++.h>
using namespace std;
const int max_e = 100000 + 10;
int T,n,m,a,b,k,l,vis[max_e],e[max_e],es[max_e],path[max_e],cnt1,cnt2;
vector<int> g[max_e];
void init() {
        scanf("%d%d%d",&n,&m,&k);
        for(int i=1;i<=n;i++) {
            g[i].clear();
            vis[i] = 0; es[i] = 0;
        }
        for(int i=0;i<k;i++) {
            scanf("%d",&a);
            es[a] = 1;
        }
        for(int i=0;i<m;i++) {
            scanf("%d%d",&a,&b);
            g[a].push_back(b); g[b].push_back(a);
        }
        scanf("%d",&l);
        for(int i=0;i<l;i++) {
            scanf("%d",&path[i]);
        }
        cnt1 = cnt2 = 0;
}
void dfs(int cur) {
    for(int i=0;i<g[cur].size();i++) {
        int u = g[cur][i];
        if(!vis[u]) {
            vis[u] = 1;
            cnt1++;
            if(es[u]) {
                es[u] = 0;
                cnt2++;
            }
            else dfs(u);
        }
    }
}
int main() {
    scanf("%d",&T);
    while(T--) {
        init();
        if(l == k) {
            cnt1 = cnt2 = 1;
            vis[path[0]] = 1;
            es[path[0]] = 0;
            for(int i=0;i<l;i++) {
                if(es[path[i]]) break;
                else dfs(path[i]);
            }
        }
        if(l == k && cnt1 == n && cnt2 == l) printf("Yes\n");
        else printf("No\n");
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: