标签:style blog http color io os ar for art
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3811
解题报告:一个无向图上有n个点和m条边,其中有k个点上安装了传感器,当有人第一次从安装了传感器的点上经过时,在控制室就会收到一个信号,现在保安制定 了一条路线目的是要将所有的点都巡逻一遍,然后在控制室收到了 L 次信号,按顺序给出收到信号的点,问这条路线是否是有可能的?
路线的不可能的情况比如收到信号的点的顺序是123,但是在无向图上要到达2这个点必定先经过3,那么这种情况就是不可能的,因为要经过2之前必定经过3,所以2之前一定会有个3.这题的思路是这样的,用dfs从第一个点开始搜,当当前点的下一个点是没有传感器的可以直接走,如果有传感器的而且刚好是路线上的下一个点,也是直接走,如果是有传感器但又不是路线上的下一个点,则先把这个点放入到一个集合里面去,当所有能走的点都走完了,再在这个集合里面找路线上的下一个点是不是在这个集合里面,最后当集合空了的时候就可以退出了,而且每次走完点之后都要标记掉。另外两个重要的就是首先要判断L 是不是等于k,因为要走完所有的点,当L小于K时,走K-L 的这些点的时候肯定会发出信号,但这些信号又不是路线上的,所以不符合。另一个是要判断这个无向图是不是个连通图,这个简单,如果不是连通图必定会有走不到的点。
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #include<vector> 6 using namespace std; 7 const int maxn = 100005; 8 vector<int> vet[maxn]; 9 int flag[maxn]; 10 int T,n,m,k,l,L[maxn],cizi[maxn],visit[maxn],is[maxn],num; 11 void find(int p,int* is) 12 { 13 if(is[p] == 1) return ; 14 num++; 15 is[p] = 1; 16 for(int i = 0;i < vet[p].size();++i) 17 find(vet[p][i],is); 18 } 19 20 int is_connect(int n) //判断是否是连通图 21 { 22 num = 0; 23 memset(is,0,sizeof(is)); 24 find(1,is); 25 return num == n; 26 } 27 void dfs(int s,int* visit,int& p) 28 { 29 if(visit[s]) return ; 30 visit[s] = 1; 31 if(flag[s]) p++; 32 for(int i = 0;i < vet[s].size();++i) 33 { 34 int nx = vet[s][i]; 35 if(flag[nx] && L[p+1] != nx) //下一个点是有传感器的,但不是当前位置上的下一个点,则加入集合 36 cizi[nx] = 1; 37 else dfs(nx,visit,p); 38 } 39 } 40 41 int main() 42 { 43 44 scanf("%d",&T); 45 while(T--) 46 { 47 scanf("%d%d%d",&n,&m,&k); 48 int a,b; 49 memset(flag,0,sizeof(flag)); //flag[i] = 1表示i点有传感器 50 for(int i = 1;i <= k;++i) 51 { 52 scanf("%d",&a); 53 flag[a] = 1; 54 } 55 for(int i = 1;i <= n;++i) 56 vet[i].clear(); 57 for(int i = 1; i<= m;++i) 58 { 59 scanf("%d%d",&a,&b); 60 vet[a].push_back(b); 61 vet[b].push_back(a); 62 } 63 scanf("%d",&l); 64 for(int i = 1;i <= l;++i) 65 scanf("%d",&L[i]); 66 if(l != k || (!is_connect(n))) //l < k或者不是连通图 67 { 68 // if(!is_connect(n)) puts("不是连通图"); 69 puts("No"); 70 continue; 71 } 72 int num_cizi = 1; 73 memset(cizi,0,sizeof(cizi)); //把集合清空 74 memset(visit,0,sizeof(visit)); 75 cizi[L[1]] = 1; //路径上的第一个点加入集合 76 int s = L[1],p = 0; //当前走到的路径上的指针 77 while(p < l && cizi[s]) 78 { 79 dfs(s,visit,p); 80 // printf("p = %d\n",p); 81 if(cizi[L[p+1]] == 1) 82 s = L[p+1]; 83 else break; 84 } 85 printf(p == l? "Yes\n":"No\n"); 86 } 87 return 0; 88 } 89 /* 90 44 91 6 6 6 92 1 2 3 4 5 6 93 1 6 94 6 3 95 6 2 96 2 3 97 2 5 98 3 4 99 6 100 1 6 2 5 3 4 101 */
标签:style blog http color io os ar for art
原文地址:http://www.cnblogs.com/xiaxiaosheng/p/3969013.html