「网络流24题」 12. 软件补丁问题

本文介绍了一种使用状压动态规划(DP)与最短路径快速算法(SPFA)来解决软件补丁问题的方法。通过将补丁的状态用二进制表示,并采用SPFA进行状态转移,解决了补丁安装过程中的最优路径寻找问题。

「网络流24题」 12. 软件补丁问题


状压 DP,SPFA 转移。

没错,跟网络流没任何关系。

b1、b2、f1、f2 都用二进制存下来,第 i 位表示是否有这个错误。

然后从每位都是 1 到 0 跑一个 SPFA 就好了。

#include <cstdio>
#include <cstring>
#include <queue>
using std::queue;
const int MAXN=1<<21,MAXM=110,INF=0x3f3f3f3f;
bool exist[MAXN];
int n,m,w[MAXM],b1[MAXM],b2[MAXM],f1[MAXM],f2[MAXM],dis[MAXN];
void Initialize(void)
{
    char s1[30],s2[30];
    for(int i=1;i<=m;++i)
    {
        scanf("\n%d%s%s",&w[i],s1,s2);
        for(int j=0,t;j<n;++j)
        {
            t=1<<j;
            if(s1[j]=='+')
                b1[i]|=t;
            else if(s1[j]=='-')
                b2[i]|=t;
            if(s2[j]=='-')
                f1[i]|=t;
            else if(s2[j]=='+')
                f2[i]|=t;
        }
    }
}
bool Skip(int i,int x)
{
    return (x|b1[i])^x || x&b2[i];
}
bool SPFA(int S,int T)
{
    queue<int> q;
    memset(dis,0x3f,sizeof dis);
    q.push(S);
    exist[S]=true;
    dis[S]=0;
    while(!q.empty())
    {
        int u=q.front();
        q.pop();
        exist[u]=false;
        for(int i=1,v;i<=m;++i)
            if(!Skip(i,u))
            {
                v=(u^(u&f1[i]))|f2[i];
                if(dis[v]>dis[u]+w[i])
                {
                    if(!exist[v])
                    {
                        q.push(v);
                        exist[v]=true;
                    }
                    dis[v]=dis[u]+w[i];
                }
            }
    }
    return dis[T]^INF;
}
int main(int argc,char** argv)
{
    scanf("%d %d",&n,&m);
    Initialize();
    printf("%d\n",SPFA((1<<n)-1,0) ? dis[0] : 0);
    return 0;
}

谢谢阅读。

转载于:https://www.cnblogs.com/Capella/p/9129246.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值