拦截匪徒问题



拦截匪徒问题

题目描述:

某市的地图是由n个点组成的无向图,每个点代表一个区。现在p区发生了抢劫案,而警察为了截住劫匪须埋伏在一个劫匪必经的区域。由于不知道劫匪会向那个区域逃窜,所以希望你计算出对于任意一个劫匪可能逃向的区域j,找出一个可以拦截劫匪的区k(k<>p,k<>j),即劫匪从p区逃向j区,必经过k区。由于地区j可能是匪徒的老巢所在,所以警察希望能在路上拦住劫匪,而不是在j区抓捕。

输入格式:

第一行位n,p (1<=p<=n<=200)

接下来位n*n的矩阵AA[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);
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值