题目链接:戳我
感觉虽然在所谓的网络流24题编制里,但是并没有看出来怎么用网络流做?(听说网络流24题全名不叫网络流24题???
看到n的范围挺小的,我们考虑状压。
转移的过程可以放到图论里面,因为要求费用最小,所以我们想到了最短路!(笑
所以就是dij+状压转移嘛qwqwq(我就是不写spfa!!!
注意一下非法情况的判断为f1里面包含,但是当前情况u不包含。或者f2里面不包含当前情况却包含了。
转移的下一个状态v对于f1的修改情况,我们这里采用减法操作,但是一定要判断这一位上是否有1再减去!(有可能本来就没有这个漏洞,所以就不需要修补啊qwq)
开始的情况为dis[(1<<n)-1],结束的情况为dis[0]。
代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#include<algorithm>
using namespace std;
int n,m,t,T;
char cur1[21],cur2[21];
struct Node
{
    int u,d;
    friend bool operator <(struct Node x,struct Node y){return x.d>y.d;}
};
int head[1050000],dis[1050000],done[1050000],b1[110][21],b2[110][21],f1[110][21],f2[110][21],cost[110];
inline bool check(int now,int x)
{
    for(int i=0;i<n;i++)
    {
        if(b1[x][i]==1&&!(now&(1<<i))) return false;
        if(b2[x][i]==1&&(now&(1<<i))) return false;
    }
    return true;
}
inline void dij()
{
    priority_queue<Node>q;
    memset(dis,0x3f,sizeof(dis));
    q.push((Node){T,0}),dis[T]=0;
    while(!q.empty())
    {
        int u=q.top().u; q.pop(); 
        if(done[u]) continue;
        done[u]=1;
        for(int i=1;i<=m;i++)
        {
            if(check(u,i)==false) continue;
            int v=u;
            for(int j=0;j<n;j++)
            {
                if(f1[i][j]) v-=v&(1<<j);
                if(f2[i][j]) v|=1<<j;   
            }
            if(dis[v]>dis[u]+cost[i])
                dis[v]=dis[u]+cost[i],q.push((Node){v,dis[v]});
        }
    }
}
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("ce.in","r",stdin);
    #endif
    scanf("%d%d",&n,&m);
    T=(1<<n)-1;
    for(int i=1;i<=m;i++)
    {
        scanf("%d%s%s",&cost[i],cur1,cur2);
        int len1=strlen(cur1),len2=strlen(cur2);
        for(int j=0;j<len1;j++)
        {
            if(cur1[j]=='+') b1[i][j]=1;
            if(cur1[j]=='-') b2[i][j]=1;
        }
        for(int j=0;j<len2;j++)
        {
            if(cur2[j]=='-') f1[i][j]=1;
            if(cur2[j]=='+') f2[i][j]=1;
        }
    }
    dij();
    printf("%d\n",dis[0]==0x3f3f3f3f?0:dis[0]);
}