首页 > 代码库 > zoj3812
zoj3812
裸BFS的题,网络赛的时候没做出来,事后才想通干掉。哭瞎。题意:在一个生产保健饮料的工厂仓库中有N个地点放了饮料,N个地点之间有M个通道。老板雇了保安夜晚来巡逻每一个存放饮料的地点。但是老板比较多疑,他在K个地点中装了传感器,由于内存限制,传感器只能显示人第一次到达该地点的时间。如果情况不安全的话,那么说明可能有另外的人进来了导致传感器记录的顺序不正常,就像是有人会穿墙或者传送之类的魔法一样。现在,需要你根据传感器的记录情况来判断情况是否安全,如果情况安全且保安能够顺利巡逻到存放饮料的每个点的话输出“Yes”,否则的话输出“No”。
我的解题思路:首先根据题意可以判断出这个由N个点M条边构成的无向图必须每两个点都能够连通,否则的话说明保安不能够巡逻每一个存放饮料的地点。然后我们根据保安必须要对每一个地点进行巡逻可以知道每个传感器都必须要记录到信息。两个“Yes”前提条件有了,现在就考虑判断顺序的事了。假设保安以第一个记录信息的传感器地点为起点,然后从这个点开始进行BFS,不继续进行BFS的条件是当前地点为安装了传感器的地点,否则的话继续BFS。接下来我们开始第二个传感器点的BFS,当然有个前提条件是在前面的点的BFS中我们必须搜索到了这个传感器点,否则说明正常情况下没办法按照当前传感器记录的顺序进行巡逻。然后依次类推。每个传感器的点都能由更早记录信息的传感器的点BFS到,那么最后我们在判断一下是否每个存放饮料的点都已经走过了,也就是判断第一个前提条件。判断后就能确定答案了。
我的解题代码:
#include <cstdio> #include <cstdlib> #include <cstring> #include <vector> #include <queue> #include <algorithm> using namespace std; #define N 100010 int vis[N],issen[N]; int s[N]; int n,m,k,kn; vector<int> g[N]; void bfs(int x) { queue <int> q; int i,a; q.push(x); while(!q.empty()) { a=q.front(); q.pop(); for(i=0; i<(int)(g[a].size()); i++) { if(!vis[g[a][i]]) { if(issen[g[a][i]]) { vis[g[a][i]]=1; continue; } else { vis[g[a][i]]=1; q.push(g[a][i]); } } } } return; } void init() { int i,a,b; memset(vis,0,sizeof(vis)); memset(issen,0,sizeof(issen)); for(i=0; i<=n; i++) g[i].clear(); scanf("%d%d%d",&n,&m,&k); for(i=0; i<k; i++) scanf("%d",&a); for(i=0; i<m; i++) { scanf("%d%d",&a,&b); g[a].push_back(b); g[b].push_back(a); } scanf("%d",&kn); for(i=0; i<kn; i++) { scanf("%d",&s[i]); issen[s[i]]=1; } return; } void process() { int i; if(k!=kn) { puts("No"); return; } vis[s[0]]=1; for(i=0; i<kn; i++) { if(!vis[s[i]]) { puts("No"); return; } bfs(s[i]); } for(i=1; i<=n; i++) if(!vis[i]) { puts("No"); return; } puts("Yes"); return; } int main() { int T; scanf("%d",&T); while(T--) { init(); process(); } return 0; }
zoj3812
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。