拦截匪徒问题
题目描述:
某市的地图是由n个点组成的无向图,每个点代表一个区。现在p区发生了抢劫案,而警察为了截住劫匪须埋伏在一个劫匪必经的区域。由于不知道劫匪会向那个区域逃窜,所以希望你计算出对于任意一个劫匪可能逃向的区域j,找出一个可以拦截劫匪的区k(k<>p,k<>j),即劫匪从p区逃向j区,必经过k区。由于地区j可能是匪徒的老巢所在,所以警察希望能在路上拦住劫匪,而不是在j区抓捕。
输入格式:
第一行位n,p (1<=p<=n<=200)
接下来位n*n的矩阵A,A[i,j]=1表示i区与j区有路连接,A[i,j]:=0则反之。
输出格式:
输出n-1行,按顺序从j=1,2,…,p-1,p+1,…,n依次输出对于每一个j,警察可以在那些点埋伏。如有多个点,要按从小到大的顺序依次输出,如没有,则对应输出“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 |
用深搜吧,但第一次的大数据都超
#include<fstream>
#include<vector>
#include<algorithm>
#define max_N 205
using namespace std;
ifstream cin("CATCH.IN");
ofstream cout("catch.txt");
int n,p,t;
bool a[max_N][max_N],v1[max_N],v2[max_N],f[max_N];
void dfs(int x,bool* v)
{
v[x]=1;
for(int i=1;i<=n;i++)
if(a[x][i] && !v[i])dfs(i,v);
}
int main()
{
cin>>n>>p;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
cin>>a[i][j];
for(int i=1;i<=n;i++)
if(a[p][i]==1)f[i]=1;
memset(v1,0,sizeof(v1));
dfs(p,v1);
for(int i=1;i<=n;i++)
{
if(i==p)continue;
if(f[i]==1)
{
cout<<"No"<<endl;
continue;
}
bool flag=0;
for(int j=1;j<=n;j++)
{
if(i==j || j==p)continue;
// if(f[j]==1)continue;
memset(v2,0,sizeof(v2));
v2[j]=1;
dfs(p,v2);
if(v1[i]==1 && v2[i]==0)
{
flag=1;
cout<<j<<' ';
}
}
if(!flag)cout<<"No";
cout<<endl;
}
// system("pause");
return 0;
}
改进后好了很多,但第八组数据不知道为什么超时严重
#include<fstream>
#include<vector>
#include<algorithm>
#define max_N 205
using namespace std;
ifstream cin("CATCH.IN");
ofstream cout("catch.txt");
vector<int>g[max_N];
int n,p,t;
bool a[max_N][max_N],v1[max_N],v2[max_N],f[max_N];
void dfs(int x,bool* v)
{
v[x]=1;
for(int i=0;i<g[x].size();i++)
if(!v[g[x][i]])dfs(g[x][i],v);
}
int main()
{
cin>>n>>p;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
cin>>a[i][j];
if(i>j && a[i][j])
{
g[i].push_back(j);
g[j].push_back(i);
}
}
for(int i=1;i<=n;i++)
if(a[p][i]==1)f[i]=1;
memset(v1,0,sizeof(v1));
dfs(p,v1);
for(int i=1;i<=n;i++)
{
if(i==p)continue;
if(f[i]==1)
{
cout<<"No"<<endl;
continue;
}
bool flag=0;
for(int j=1;j<=n;j++)
{
if(i==j || j==p)continue;
// if(f[j]==1)continue;
memset(v2,0,sizeof(v2));
v2[j]=1;
dfs(p,v2);
if(v1[i]==1 && v2[i]==0)
{
flag=1;
cout<<j<<' ';
}
}
if(!flag)cout<<"No";
cout<<endl;
}
// system("pause");
return 0;
}
下面的再稍稍改进了一下,但没啥大用
#include<fstream>
#include<vector>
#include<algorithm>
#define max_N 205
using namespace std;
ifstream cin("CATCH.IN");
ofstream cout("catch.txt");
vector<int>g[max_N];
int n,p,t,i,j;
bool a[max_N][max_N],v1[max_N],v2[max_N],f[max_N];
void dfs1(int x,bool* v)
{
v[x]=1;
for(int i=0;i<g[x].size();i++)
if(!v[g[x][i]])dfs1(g[x][i],v);
}
void dfs2(int x,bool f,bool* v);
int main()
{
cin>>n>>p;
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
{
cin>>a[i][j];
if(i>j && a[i][j])
{
g[i].push_back(j);
g[j].push_back(i);
}
}
for(i=1;i<=n;i++)
if(a[p][i]==1)f[i]=1;
memset(v1,0,sizeof(v1));
dfs1(p,v1);
for(i=1;i<=n;i++)
{
if(i==p)continue;
if(f[i]==1)
{
cout<<"No"<<endl;
continue;
}
bool flag=0;
for(j=1;j<=n;j++)
{
if(i==j || j==p)continue;
// if(f[j]==1)continue;
memset(v2,0,sizeof(v2));
v2[j]=1;
dfs2(p,0,v2);
if(v1[i]==1 && v2[i]==0)
{
flag=1;
cout<<j<<' ';
}
}
if(!flag)cout<<"No";
cout<<endl;
}
// system("pause");
return 0;
}
void dfs2(int x,bool f,bool* v)
{
v[x]=1;
if(x==i){f=1;return;}
for(int k=0;k<g[x].size();k++)
if(!v[g[x][k]] && !f)
dfs2(g[x][k],0,v);
}