【网络流24题】软件补丁问题

来源:互联网 发布:蜂窝移动数据开启无效 编辑:程序博客网 时间:2024/05/21 08:58

(网络流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;}
0 0