[网络流24题]软件补丁问题

Posted birchtree

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[网络流24题]软件补丁问题相关的知识,希望对你有一定的参考价值。

分析

裸的最短路:

把错误集合状压成一个二进制,第i为为1表示有第i个错误

把这个状态x作为图上的节点编号,dist[x]表示转移到状态x需要的时间

显然初始状态为dist[\(2^n-1\)]最终的答案为dist[0]

转移的时候枚举每一个补丁,通过位运算判断补丁i是否能修复当前状态

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define maxm 1005
#define maxn 1<<21 
#define INF 0x3f3f3f3f
using namespace std;
int n,m;
char s[maxm];
int t[maxm];
int b1[maxm],b2[maxm],f1[maxm],f2[maxm];

int dist[maxn];
int inq[maxn];
int spfa(int s){
    queue<int>q;
    memset(dist,0x3f,sizeof(dist));
    q.push(s);
    dist[s]=0;
    inq[s]=1;
    while(!q.empty()){
        int x=q.front();
        q.pop();
        inq[x]=0;
        for(int i=1;i<=m;i++){//枚举每一个补丁
            if((b1[i]|x)==x&&(b2[i]&x)==0){//x包括b1[i],不包括b2[i]
                int y=x^(x&f1[i]);//x&f1[i]为x中能被修复的错误,再异或就相当于把错误去掉
                y|=f2[i];//加上新增的错误
                if(dist[y]>dist[x]+t[i]){
                    dist[y]=dist[x]+t[i];
                    if(!inq[y]){
                        q.push(y);
                        inq[y]=1;
                    }
                }
            }
        }
    }
    if(dist[0]==INF) return 0;
    else return dist[0];
}
int main(){
    scanf("%d %d",&n,&m);
    for(int i=1;i<=m;i++){
        scanf("%d",&t[i]);
        scanf("%s",s);
        for(int j=0;j<n;j++){
            if(s[j]=='+') b1[i]|=(1<<j);
            else if(s[j]=='-') b2[i]|=(1<<j);
        }
        scanf("%s",s);
        for(int j=0;j<n;j++){
            if(s[j]=='-') f1[i]|=(1<<j);
            else if(s[j]=='+') f2[i]|=(1<<j);
        }
    }
    printf("%d\n",spfa((1<<n)-1));
} 

以上是关于[网络流24题]软件补丁问题的主要内容,如果未能解决你的问题,请参考以下文章

[网络流24题]软件补丁问题

[网络流24题] 软件补丁问题

网络流24题软件补丁问题(最短路)

COGS439. [网络流24题] 软件补丁

网络流24题 No.12 软件补丁问题(最小转移代价 最短路)

网络流24题----04软件补丁问题魔术球问题