1. 程式人生 > >vijos1026-隱式圖搜尋(回溯|spfa)-毒藥?毒藥

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;
}