vijos1026-隐式图搜索(回溯|spfa)-毒药?毒药

https://vijos.org/p/1026
给定m个病和n个药,每个药对m个病有三种可能的情况,1可以治愈,-1当没病时生病,0 无效。问至少多少药,可以使病全部治好,如果不可以的话,就输出”The patient will be dead.”
思路:讲真我真的不知道这是隐式图搜索什么鬼,不过一说最少,不是bfs就是动态规划(dfs其实也能写,不过一般都麻烦)wa了好几发,因为对药的规则不是特别了解。
自己列个表就能清楚 (这是上周写的题,演草纸找不到了qwq)。 只有两种情况可以转移:
1 自己有病,但是这个药可以治(是1)。
2 自己没病,但是这个药时-1
code one:回溯的思路,(感觉自己回溯什么的都写不利索了,还是太弱)

#include <bits/stdc++.h>

using namespace std;
/* 用一个map来存一下,然后暴力搜索
*/
typedef long long ll;
const int maxn=200;
vector<int>q[maxn];
bool vis[maxn];
int m,n;
int ans;
const int mx=1<<11;
int mp[mx];
void dfs(ll sta,int num){
     //cout<<" "<<num<<endl;
     if(num>n)return;
      if(mp[sta]<=num)return;
      mp[sta]=num;
        if(sta==0){
            ans=min(ans,num);
            return;
        }
     for(int j=1;j<=n;j++){
              if(vis[j])continue;
              ll sta1=sta;
         for(int i=0;i<q[j].size();i++){
             if(q[j][i]==1&&((1<<i)&sta1)){
               sta1^=(1<<i);
             }
             else if(q[j][i]==-1&&!((sta&(1<<i)))){
               sta1^=(1<<i);
             }
         }
         vis[j]=true;
          dfs(sta1,num+1);
          vis[j]=false;
     }
     return;
}
int main()
{   int a;
    scanf("%d%d",&m,&n);
    ans=1e7;
    memset(mp,0x3f,sizeof(mp));
    for(int i=1;i<=n;i++){
        for(int j=0;j<m;j++){
            scanf("%d",&a);
            q[i].push_back(a);
        }
    }
    ll s=(1<<m)-1;
    dfs(s,0);
    if(ans==1e7){
         puts("The patient will be dead.");
    }
    else{
        printf("%d\n",ans);
    }
    return 0;
}

code two: 用spfa

#include <bits/stdc++.h>

using namespace std;
/*   回溯的时候t了。
     用一个map剪枝会好很多。
     还有没有弄清题意。
*/
typedef long long ll;
const int maxn=200;
vector<int>q[maxn];
const int mx=1<<11;
bool vis[mx];
int d[mx];
int m,n;
void spfa(ll s){
     queue<ll>qu;
     memset(d,0x3f,sizeof(d));
     memset(vis,false,sizeof(vis));
     d[s]=0;
     vis[s]=true;
     qu.push(s);
     while(!qu.empty()){
           ll u=qu.front();
                qu.pop();
            vis[u]=false;
            if(!u){
                printf("%d\n",d[0]);
                break;
            }
            for(int i=1;i<=n;i++){
                ll sta=u;
                for(int j=0;j<m;j++){
                    if(q[i][j]==1&&((1ll<<j)&u)){
                       sta^=(1<<j);
                    }else if(q[i][j]==-1&&!((1ll<<j)&u)){
                         sta^=(1<<j);
                    }
                }
                if(d[sta]>d[u]+1){
                 d[sta]=d[u]+1;
                   if(!vis[sta]){
                    vis[sta]=true;
                    qu.push(sta);
                   }
                }
            }
     }
     if(d[0]==0x3f3f3f3f){
         puts("The patient will be dead.");
     }
     else{
        ;
     }



}
int main()
{   int a;
    scanf("%d%d",&m,&n);
    for(int i=1;i<=n;i++){
        for(int j=0;j<m;j++){
            scanf("%d",&a);
            q[i].push_back(a);
        }
    }
    ll s=(1<<m)-1;
    //dfs(s,0);
    spfa(s);
    return 0;
}
阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_35781950/article/details/79952624
个人分类: 搜索
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭