记录一个菜逼的成长。。
ps:话说这题跟网络流没关系吧。。
loj的题目有错,第二个字符串里
+
是属于
有
n
个错,所以一开始的状态是
然后根据题目的约束条件跑最短路即可。
#include <bits/stdc++.h>
using namespace std;
#define rep(i,l,r) for( int i = l; i <= r; i++ )
#define rep0(i,l,r) for( int i = l; i < r; i++ )
#define ALL(v) (v).begin(),(v).end()
#define cl(a,b) memset(a,b,sizeof(a))
#define clr clear()
#define pb push_back
#define mp make_pair
#define fi first
#define se second
const int INF = 0x3f3f3f3f;
const int maxn = 100 + 10;
struct Node{
int b1,b2,f1,f2,w;
}a[maxn];
char str[maxn];
int dis[1<<21],vis[1<<21],n,m;
bool check(int x,int i)
{
if((x | a[i].b1) != x)return false;//包含b1的所有错误
if(x & a[i].b2)return false;//不包含b2的所有错误
return true;
}
int bfs(int s,int t)
{
queue<int>q;
q.push(s);
cl(vis,0),cl(dis,INF);
vis[s] = 1;dis[s] = 0;
while(!q.empty()){
int f = q.front();q.pop();
vis[f] = 0;
rep(i,1,m){
if(check(f,i)){
int to = (f & (~a[i].f1)) | a[i].f2;
if(dis[to] > dis[f] + a[i].w){
dis[to] = dis[f] + a[i].w;
if(!vis[to]){
vis[to] = 1;
q.push(to);
}
}
}
}
}
return dis[t] != INF ? dis[t] : 0;
}
int main()
{
scanf("%d%d",&n,&m);
rep(i,1,m){
scanf("%d%s",&a[i].w,str);
rep0(j,0,n){
if(str[j] == '+')a[i].b1 |= (1<<j);
if(str[j] == '-')a[i].b2 |= (1<<j);
}
scanf("%s",str);
rep0(j,0,n){
if(str[j] == '+')a[i].f2 |= (1<<j);
if(str[j] == '-')a[i].f1 |= (1<<j);
}
}
int s = (1<<n) - 1,t = 0 ;
printf("%d\n",bfs(s,t));
return 0;
}