状压 + spfa
https://loj.ac/problem/6009
#include <iostream> #include <cstring> #include <stdio.h> #include <queue> using namespace std; const int maxn = 109; struct CC{ int b1,b2,f1,f2,w; }cc[maxn]; int n,m; int dis[1<<20]; int vis[1<<20]; int spfa(int S,int T){ memset(dis,0x3f,sizeof(dis)); memset(vis,0,sizeof(vis)); dis[S] = 0; vis[S] = 1; queue<int> q; q.push(S); while(!q.empty()){ int now = q.front(); q.pop(); vis[now] = 0; for(int i=1;i<=m;i++){ if(((~now)&cc[i].b1)==0 && (now&cc[i].b2)==0){ int v = (now&(~cc[i].f1))|cc[i].f2; if(v>=(1<<n) || v<0) continue; int w = cc[i].w; if(dis[v]>dis[now]+w){ dis[v] = dis[now]+w; if(vis[v]==0) { vis[v] = 1; q.push(v); } } } } } if(dis[T]==0x3f3f3f3f){ return 0; }else{ return dis[T]; } } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=m;i++){ cc[i] = (CC){0,0,0,0,0}; int w; char str1[30],str2[30]; scanf("%d%s%s",&w,str1,str2); cc[i].w = w; for(int j=0;j<n;j++){ if(str1[j]==‘-‘){ cc[i].b2|=(1<<j); }else if(str1[j]==‘+‘){ cc[i].b1|=(1<<j); } if(str2[j]==‘-‘){ cc[i].f1|=(1<<j); }else if(str2[j]==‘+‘){ cc[i].f2|=(1<<j); } } } int ans = spfa((1<<n)-1,0); printf("%d\n",ans); return 0; }