练手CF3-C

深搜,亮点在那个剪枝,flag代表是否搜索数组从开始到当前一直等于原始数组同位置的数,如果是真,就从原始数组的当前位置的书开始搜,否则就从0开始搜。

见代码。

#include <iostream>
#include <cstring>

using namespace std;
int n,m,beg,origin[2003];
int mp[103][103];
bool vis[103][103];
int cnt;
int stk[2010];
bool check()
{
    int i;
    for(i=0;i<=m;i++)
    {
        if(stk[i]==origin[i])
            continue;
        if(stk[i]<origin[i])
            return false;
        if(stk[i]>origin[i])
           return true;
    }
    return false;
}

void dfs(int bg,bool flag)
{
//    cout<<cnt<<endl;
    if(cnt==m+1)
    {
//        for(int i=0;i<=m;i++)
//            cout<<stk[i]<<' ';
//        cout<<endl;
        if(stk[cnt-1]==beg&&check())
        {
            return;
        }
        else
        {
            return;
        }
    }
    for(int i=1;i<=n;i++)
    {
        if(flag&&i<origin[cnt])
            continue;
        if(mp[bg][i]&&!vis[bg][i])
        {
            vis[bg][i]=true;
            vis[i][bg]=true;
            stk[cnt++]=i;
            dfs(i,flag&&i==origin[cnt-1]);
//            cout<<stk[cnt]<<endl;
            if(cnt==m+1&&stk[cnt-1]==beg&&check())
                return;
//                cout<<" "<<cnt<<endl;
            cnt--;
//            cout<<"  "<<cnt<<endl;
            vis[bg][i]=false;
            vis[i][bg]=false;
        }
    }
    return;
}
int main()
{
    cin>>n>>m;
    int i;
    cnt=1;
    memset(mp,0,sizeof(mp));
    memset(vis,false,sizeof(vis));
    cin>>origin[0];
    beg=origin[0];
    for(i=1;i<=m;i++)
    {
        cin>>origin[i];
        mp[origin[i-1]][origin[i]]=1;
        mp[origin[i]][origin[i-1]]=1;
    }
////    for(i=1;i<=n;i++)
//////    {
//////        for(int j=1;j<=n;j++)
//////            cout<<mp[i][j]<<' ';
//////        cout<<endl;
////    }
    stk[0]=beg;
    dfs(beg,true);
//    cout<<cnt<<endl;
    if(cnt==m+1)
    {
        for(i=0;i<=m;i++)
            cout<<stk[i]<<' ';
        cout<<endl;
    }
    else
        cout<<"No solution"<<endl;
    return 0;
}

  

原文地址:https://www.cnblogs.com/aljxy/p/3415684.html