ZOJ-3811 Untrusted Patrol DFS 2014牡丹江網路賽C題,zoj-3811untrusted
n個點,m條雙向邊,k個感應器。其中有l個感應器記錄到了第一次到達的時間順序,求是否有可能檢查了所有的頂點。
首先判斷l,l<k一定是不行的。然後按照感應器的時間順序dfs,先從第一個感應器位置搜尋dfs搜到所有的到達感應器的位置結束,如果這個感應器被標記為可訪問,則從這個感應器繼續搜尋下一層感應器,否則是不能滿足時間順序的。最後還要判斷整個圖的連通性,所有的頂點都要可以到達的。
#include <iostream>#include <cstdio>#include <cstring>#include <queue>#include <cmath>#include <iomanip>#include <cstdlib>#include <algorithm>using namespace std;const int maxn=110000;int head[maxn];int visit[maxn];int pile[maxn];int n,m,k,l;int num;int s;struct Edge{int u,v;int next;}edge[maxn*4];void addedge(int u,int v){edge[num].u=u;edge[num].v=v;edge[num].next=head[u];head[u]=num++;edge[num].u=v;edge[num].v=u;edge[num].next=head[v];head[v]=num++;}void dfs(int u){visit[u]=1;for(int i=head[u];i!=-1;i=edge[i].next){int v=edge[i].v;if(visit[v]){continue;}if(pile[v]){visit[v]=1;continue;}dfs(v);}}void dfs1(int u){visit[u]=1;s++;for(int i=head[u];i!=-1;i=edge[i].next){int v=edge[i].v;if(!visit[v]){dfs1(v);}}}int main(){int t;int flag;int u,v;scanf("%d",&t);while(t--){flag=1;s=0;num=0;memset(head,-1,sizeof(head));memset(visit,0,sizeof(visit));memset(pile,0,sizeof(pile));scanf("%d%d%d",&n,&m,&k);for(int i=0;i<k;i++){scanf("%d",&u);pile[u]=1;}for(int i=0;i<m;i++){scanf("%d%d",&u,&v);addedge(u,v);}scanf("%d",&l);if(l<k){flag=0;}scanf("%d",&u);dfs(u);for(int i=1;i<l;i++){scanf("%d",&u);if(!visit[u]){flag=0;}if(flag){dfs(u);}}memset(visit,0,sizeof(visit));dfs1(1);if(s<n){flag=0;}if(flag){printf("Yes\n");}else{printf("No\n");}}return 0;}