题解:CF1846G Rudolf and CodeVid-23
Solution CF1846G
Idea
注意到
然后最短路转移就枚举初始状态
那么问题来了:末状态
设
那么
至于副作用,与刚才的副作用之前的值或一下就行。这个理解起来很容易:只要这一个药可以产生,或者之前就得了,就会患。
然后枚举初状态
Code
#include<bits/stdc++.h>
using namespace std;
const int N=10;
int get(string s){
int res=0,t=1;
for(int i=0;i<s.length();i++){
res=res+t*(s[i]=='1');
t<<=1;
}
return res;
}
int n,m,dis[1<<N],vis[1<<N];
string tmp;
struct node{
int x,y,t;
}a[1005];
void solve(){
scanf("%d%d",&n,&m);
for(int i=0;i<(1<<n);i++){
dis[i]=0x3f3f3f3f;
vis[i]=0;
}
cin>>tmp;
dis[get(tmp)]=0;
for(int i=1;i<=m;i++){
cin>>a[i].t;
cin>>tmp;
a[i].x=get(tmp);
cin>>tmp;
a[i].y=get(tmp);
}
while(1){
int u=-1;
for(int i=0;i<(1<<n);i++){
if(vis[i]||dis[i]==0x3f3f3f3f)continue;
if(u==-1||dis[i]<dis[u]){
u=i;
}
}
if(u==-1)break;
vis[u]=1;
for(int i=1;i<=m;i++){
int w=a[i].t;
int v=(u&(((1<<n)-1)^a[i].x))|a[i].y;
dis[v]=min(dis[v],dis[u]+w);
}
}
cout<<(dis[0]==0x3f3f3f3f ? -1 : dis[0])<<endl;
}
int main(){
int T;cin>>T;
while(T--)solve();
}