(网络流24题大多需要spj,所以需要一个有spj的oj,本系列代码均在www.oj.swust.edu.cn测试通过)
不知道为什么会有这种奇怪的东西混进我的网络流,但既然出现了就写一下吧,大体思路就是用二进制表示状态,然后每个状态可以转移到另一个状态,求一个最短路即可。
TMD我F1和F2看反了,读题杀真是没救了。
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<iostream>
#include<iomanip>
#include<ctime>
#include<cmath>
#include<algorithm>
#include<queue>
using namespace std;
int b1[10000];
int b2[10000];
int f1[10000];
int f2[10000];
char s[10000];
int dis[2<<21];
bool vis[2<<21];
int v[5000];
queue<int> que;
int n,m;
void spfa()
{
memset(dis,0x3f,sizeof dis);
dis[(1<<n)-1] = 0;
que.push((1<<n)-1);
int now;
while(!que.empty())
{
now = que.front();
vis[now] = false;
que.pop();
for(int i=1,x,y;i<=m;++i)
if(!(now&b2[i]) && (now|b1[i])==now)
{
x = now;
x &= (~f1[i]);
x |= f2[i];
if(dis[x]>dis[now]+v[i])
{
dis[x] = dis[now]+v[i];
if(!vis[x]){
vis[x] = true;
que.push(x);
}
}
}
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
scanf("%d",&v[i]);
scanf("%s",s+1);
int len=strlen(s+1);
for(int j=1;j<=len;j++)
{
if(s[j]=='+') b1[i]=(b1[i]|(1<<(j-1)));
else if(s[j]=='-') b2[i]=(b2[i]|(1<<(j-1)));
}
scanf("%s",s+1);
len=strlen(s+1);
for(int j=1;j<=len;j++)
{
if(s[j]=='+') f1[i]=(f1[i]|(1<<(j-1)));
else if(s[j]=='-') f2[i]=(f2[i]|(1<<(j-1)));
}
swap(f1[i],f2[i]);
}
spfa();
if(dis[0]==0x3f3f3f3f) cout<<0;
else cout<<dis[0];
return 0;
}