zoj 3811 Untrusted Patrol (按照顺序访问点+并查集||宽搜)
2014-09-11 10:57
330 查看
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3811
题意:
有n个点,其中有k个点是有摄像头的,然后会给出L个有序的点,要求按照顺序访问(后面没有被访问过的有摄像头的点,不能走)。
并查集:
首先遍历整张图,要将所有的无关点(没有摄像头的点),相同的合并到一个集合里面,然后在将有关点一个一个的合并进去,要是有不在一个集合的,那么就是走不通的
用vector的版本(最开始vector一直没有清空,导致wrong了很多次)
宽搜:
按照顺序,从每个有摄像头的地方顺次的搜索,直到不能扩展为止,那么当第seq[i]这个点扩展完整为止,要是seq[i+1]这个没有被扩展到,那么一定不能完成任务了。
题意:
有n个点,其中有k个点是有摄像头的,然后会给出L个有序的点,要求按照顺序访问(后面没有被访问过的有摄像头的点,不能走)。
并查集:
首先遍历整张图,要将所有的无关点(没有摄像头的点),相同的合并到一个集合里面,然后在将有关点一个一个的合并进去,要是有不在一个集合的,那么就是走不通的
用vector的版本(最开始vector一直没有清空,导致wrong了很多次)
#include<stdio.h> #include<string.h> #include<vector> #define mt(a,b) memset(a,b,sizeof(a)) #define MAX 100009 using namespace std; int point[MAX],seq[MAX]; bool mark[MAX]; vector <int> vec[MAX]; struct Node { int s; int e; } edge[MAX*2]; struct Ele { int parent; int num; } elem[MAX]; void make_set(int n) { for(int i=1; i<=n; i++) { elem[i].parent=i; elem[i].num=1; } } int Find(int x) { int root,temp; temp=x; while(x!=elem[x].parent) //寻找根节点 x=elem[x].parent; root=x; x=temp; while (x!=elem[x].parent) {//压缩路径,全部赋值为根节点的值 temp=elem[x].parent; elem[x].parent=root; x=temp; } return root; } void Union(int a,int b) { //合并两个集合 int x,y; x=Find(a); y=Find(b); if(elem[x].num>=elem[y].num) { elem[y].parent=elem[x].parent; elem[x].num+=elem[y].num; } else { elem[x].parent=elem[y].parent; elem[y].num+=elem[x].num; } } int main() { int T,n,m,k,L; scanf("%d",&T); while(T--) { memset(mark,false,sizeof(mark)); scanf("%d %d %d",&n,&m,&k); for(int i=0; i<k; i++) { scanf("%d",&point[i]); mark[point[i]]=true; } for(int i=0;i<=n;i++) vec[i].clear(); for(int i=0; i<m; i++) { scanf("%d %d",&edge[i].s,&edge[i].e); vec[edge[i].s].push_back(edge[i].e); vec[edge[i].e].push_back(edge[i].s); } scanf("%d",&L); for(int i=0; i<L; i++) { scanf("%d",&seq[i]); } if(L!=k) { printf("No\n"); continue; } make_set(n); int len; bool flag=false; mark[seq[0]]=false; for(int i=1;i<=n;i++){ if(mark[i]==false){ len=vec[i].size(); for(int j=0;j<len;j++){ if(mark[vec[i][j]]==false){ Union(i,vec[i][j]); } } } } len=vec[seq[0]].size(); for(int i=0; i<len; i++) { if(mark[vec[seq[0]][i]]==false) Union(seq[0],vec[seq[0]][i]); } for(int i=1; i<L; i++) { mark[seq[i]]=false; len=vec[seq[i]].size(); for(int j=0; j<len; j++) { if(mark[vec[seq[i]][j]]==false) { Union(seq[i],vec[seq[i]][j]); } } int fa = Find(seq[i-1]); int fb = Find(seq[i]); if(fa!=fb) { flag=true; break; } } bool flag1=false; int fa=Find(1); for(int i=2; i<=n; i++) { int fb=Find(i); if(fa!=fb) { flag1=true; break; } } if(flag==false&&flag1==false) printf("Yes\n"); else printf("No\n"); } return 0; }
宽搜:
按照顺序,从每个有摄像头的地方顺次的搜索,直到不能扩展为止,那么当第seq[i]这个点扩展完整为止,要是seq[i+1]这个没有被扩展到,那么一定不能完成任务了。
#include<stdio.h> #include<string.h> #include<vector> #include<queue> #define MAX 100009 using namespace std; vector <int> vec[MAX]; bool mark[MAX];//用于标记是否有路灯 bool used[MAX];//标记找一对顶点的过程中的点,是否被访问过 struct Node{ int s; int e; }edge[2*MAX]; int point[MAX],seq[MAX]; void deal(int f) { queue<int>Que; while(!Que.empty()) Que.pop(); Que.push(f); used[f]=true; mark[f]=false; while(!Que.empty()) { int tmp=Que.front(); Que.pop(); //printf("~~%d\n",tmp); if(mark[tmp]==false) { int len=vec[tmp].size(); for(int i=0; i<len; i++) { if(used[vec[tmp][i]]==false) { Que.push(vec[tmp][i]); used[vec[tmp][i]]=true; } } } } } int main() { int T,n,m,k,L; scanf("%d",&T); while(T--) { scanf("%d %d %d",&n,&m,&k); memset(mark,false,sizeof(mark)); for(int i=0;i<=n;i++) vec[i].clear(); for(int i=0; i<k; i++) { scanf("%d",&point[i]); mark[point[i]]=true; } for(int i=0; i<m; i++) { scanf("%d %d",&edge[i].s,&edge[i].e); vec[edge[i].s].push_back(edge[i].e); vec[edge[i].e].push_back(edge[i].s); } scanf("%d",&L); for(int i=0; i<L; i++) { scanf("%d",&seq[i]); } if(L!=k) { printf("No\n"); continue; } int i; memset(used,false,sizeof(used)); deal(seq[0]); for(i=1; i<L; i++) { if(used[seq[i]]==false) break; deal(seq[i]); } bool num=false; for(int j=1;j<=n;j++){ if(used[j]==false) { num=true; break; } } if(i==L&&num==false) printf("Yes\n"); else printf("No\n"); } return 0; }
相关文章推荐
- ZOJ 3811 Untrusted Patrol【并查集】
- Zoj 3811 Untrusted Patrol 求连通顺序
- ZOJ 3811 Untrusted Patrol 并查集 染色 BFS
- ZOJ 3811 Untrusted Patrol 并查集+邻接表,注意所有点都要走过
- ZOJ 3811 Untrusted Patrol 并查集
- ZOJ 3811 Untrusted Patrol 并查集
- ZOJ_3811_Untrusted Patrol(并查集)
- ZOJ 3811 —— Untrusted Patrol(2014牡丹江网络赛C题)
- ZOJ 3811 Untrusted Patrol The 2014 ACM-ICPC Asia Mudanjiang Regional First Round
- ZOJ 3811 Untrusted Patrol dfs
- zoj 3811 untrusted patrol
- zoj 3811 Untrusted Patrol 牡丹江网络赛c题
- ZOJ Problem Set - 3811 Untrusted Patrol
- ZOJ 3811 Untrusted Patrol 标记+dfs
- ZOJ 3811 Untrusted Patrol
- zoj 3811 Untrusted Patrol(bfs或dfs)
- ZOJ 3811-Untrusted Patrol(DFS)
- zoj 3811 Untrusted Patrol The 2014 ACM-ICPC Asia Mudanjiang Regional First Round C
- ZOJ 3811 Untrusted Patrol(dfs+并查集)
- ZOJ 3811 Untrusted Patrol(BFS)