【7.13考试第二题】RQNOJ190 拦截匪徒
2016-07-15 14:00
295 查看
【问题描述】
某城市的地图是一个由N个点组成的无向图,每个点代表一个区。现在p区发生抢劫案,而警察为了截住劫匪须埋伏在一个劫匪必经区域。由于不知道劫匪会向哪个区逃窜,所以市长要求对于任意一个劫匪可能逃向的区j,找出一个可以拦截劫匪的区域k(k!=p,k!=j),即劫匪从p区逃向j区,必须经过k区。由于地区j可能为匪徒的老巢所在,所以警察希望能在路上拦截住土匪,而不是在j区抓获。
【输入格式】
第一行N,p,接下来得为N*N的矩阵A,A[i][j]=1,表示i与j右路相连,A[i][j]=0则没有。
【输出格式】
输出N-1行,输出警察应在哪个些置埋伏,按j=1、2、…p-1、p+1、…N的顺序输出,若有多点,由小到大顺序输出。如果没有合适的埋伏位置,或者在p与j根本就不连通,则输出No。
【输入输出样例1】
输入
5 1
0 1 1 0 0
1 0 1 1 0
1 1 0 0 0
0 1 0 0 1
0 0 0 1 0
输出
No
No
2
2 4
【数据范围】
1<=N,p<=300
如题,题目的意思是给你一张无向图,然后删除一个点,看p->j是否连通。
故枚举终点j和警察埋伏点k,然后判断删去k后p和j是否仍然连通,如果不连通则说明这个点可行,压入变长数组中,根据变长数组中元素个数输出。
当然每一个枚举的终点j应和p连通(用并查集或BFS判断)
一点“辛酸”的总结:
最后做的这个题,这个题其实算不上难题,但是比较坑,一开始读题的时候找不到什么思路,直接跳过了,后来开始做的时候已经是4点了,还有一个小时,感觉比较急,直接就开始做了,觉得是枚举删去埋伏的那个点然后二分图判定,完美打偏了,后来想到直接判定连通性,已经4点半了,又觉得BFS要TLE,然后用并查集假删除。做得很复杂,调的时候也总是不对。下次做题还是不能太急,不管有多少时间都要慢慢来,还有就是高级方法不好做不如想想其他看似低级的方法。
(看到这题解的枚举范围,我的内心毫无波澜)
某城市的地图是一个由N个点组成的无向图,每个点代表一个区。现在p区发生抢劫案,而警察为了截住劫匪须埋伏在一个劫匪必经区域。由于不知道劫匪会向哪个区逃窜,所以市长要求对于任意一个劫匪可能逃向的区j,找出一个可以拦截劫匪的区域k(k!=p,k!=j),即劫匪从p区逃向j区,必须经过k区。由于地区j可能为匪徒的老巢所在,所以警察希望能在路上拦截住土匪,而不是在j区抓获。
【输入格式】
第一行N,p,接下来得为N*N的矩阵A,A[i][j]=1,表示i与j右路相连,A[i][j]=0则没有。
【输出格式】
输出N-1行,输出警察应在哪个些置埋伏,按j=1、2、…p-1、p+1、…N的顺序输出,若有多点,由小到大顺序输出。如果没有合适的埋伏位置,或者在p与j根本就不连通,则输出No。
【输入输出样例1】
输入
5 1
0 1 1 0 0
1 0 1 1 0
1 1 0 0 0
0 1 0 0 1
0 0 0 1 0
输出
No
No
2
2 4
【数据范围】
1<=N,p<=300
如题,题目的意思是给你一张无向图,然后删除一个点,看p->j是否连通。
故枚举终点j和警察埋伏点k,然后判断删去k后p和j是否仍然连通,如果不连通则说明这个点可行,压入变长数组中,根据变长数组中元素个数输出。
当然每一个枚举的终点j应和p连通(用并查集或BFS判断)
一点“辛酸”的总结:
最后做的这个题,这个题其实算不上难题,但是比较坑,一开始读题的时候找不到什么思路,直接跳过了,后来开始做的时候已经是4点了,还有一个小时,感觉比较急,直接就开始做了,觉得是枚举删去埋伏的那个点然后二分图判定,完美打偏了,后来想到直接判定连通性,已经4点半了,又觉得BFS要TLE,然后用并查集假删除。做得很复杂,调的时候也总是不对。下次做题还是不能太急,不管有多少时间都要慢慢来,还有就是高级方法不好做不如想想其他看似低级的方法。
(看到这题解的枚举范围,我的内心毫无波澜)
#include<cstdio> #include<iostream> #include<queue> #include<cstring> #include<algorithm> #include<vector> #define maxn 305 using namespace std; int n,p,rear,front; int pa[2*maxn],id[2*maxn],vis[2*maxn],q[2*maxn]; vector<int>ep; vector<int>g[maxn]; void initial() { for(int i=1;i<=n;i++)pa[i]=i,id[i]=i; } int find(int x) { return pa[x] = pa[x]==x? x:find(pa[x]); } void Union(int x,int y) { pa[find(x)]=find(y); } bool judge(int x,int y) { return find(x)==find(y); } void BFS(int s) { rear=front=1; q[rear++]=s; vis[s]=1; while(rear!=front) { int i=q[front++]; for(int k=0;k<g[i].size();k++) { int j=g[i][k]; if(vis[j])continue; vis[j]=1; q[rear++]=j; } } } int main() { //freopen("my.in","r",stdin); //freopen("my.out","w",stdout); scanf("%d%d",&n,&p); initial(); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { int x; scanf("%d",&x); if(x==1) { g[i].push_back(j); Union(i,j); } } for(int i=1;i<=n;i++)if(i!=p) { ep.clear(); for(int k=1;k<=n;k++)if(k!=p && k!=i)//假设删除k { memset(vis,0,sizeof(vis)); vis[k]=1; BFS(p); if(!vis[i]) ep.push_back(k); } if(ep.size()>0 && judge(p,i)) { for(int k=0;k<ep.size();k++) printf("%d ",ep[k]); printf("\n"); } else printf("No\n"); } return 0; }
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- 关于指针的一些事情
- c++ primer 第五版 笔记前言
- share_ptr的几个注意点
- Lua中调用C++函数示例
- Lua教程(一):在C++中嵌入Lua脚本
- Lua教程(二):C++和Lua相互传递数据示例
- C++联合体转换成C#结构的实现方法
- C++高级程序员成长之路
- C++编写简单的打靶游戏
- C++ 自定义控件的移植问题
- C++变位词问题分析
- C/C++数据对齐详细解析
- C++基于栈实现铁轨问题
- C++中引用的使用总结
- 使用Lua来扩展C++程序的方法
- C++中调用Lua函数实例
- Lua和C++的通信流程代码实例
- C++的template模板中class与typename关键字的区别分析
- C与C++之间相互调用实例方法讲解