【问题描述】
某城市的地图是一个由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的顺序输出,若有多点,由小到大顺序输出,如没有则输出No。
【输入样例】
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
这道题就是简单的暴力枚举,枚举每个点删除后能否到达目标点,就可以得到答案,但要注意一开始就不连通的情况(这就是我错的原因了)。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<vector>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn=305;
vector<int >g[maxn];
int n,m,vis[maxn];
void init()
{
memset(vis,0,sizeof(vis));
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
int x;
scanf("%d",&x);
if(x) g[i].push_back(j);
}
}
void bfs(int y,int z)
{
queue<int>q;
q.push(m);
vis[m]=1;
while(!q.empty())
{
int x=q.front();
q.pop();
for(int i=0;i<g[x].size();i++)
{
int j=g[x][i];
if(j==y) continue;
if(vis[j])
continue;
vis[j]=1;
q.push(j);
}
}
}
int main()
{
freopen("catch.in","r",stdin);
//freopen("catch.out","w",stdout);
init();
for(int i=1;i<=n;i++) if(i!=m)
{
memset(vis,0,sizeof(vis));
bfs(m,m);
if(vis[i]==0)
{
printf("No\n");
continue;
}
int ans=0;
for(int j=1;j<=n;j++)
if(j!=i&&j!=m)
{
int ok=0;
memset(vis,0,sizeof(vis));
bfs(j,i);
if(vis[i]==0)
{
ans++;
printf("%d ",j);
}
}
if(ans==0) printf("No");
printf("\n");
}
return 0;
}