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

题意:某公司发现其研制的一个软件中有 n个错误,随即为该软件发放了一批共 m 个补丁程序。对于每一个补丁 i ,都有 2 个与之相应的错误集合 B1(i)和 B2(i),使得仅当软件包含 B1(i)中的所有错误,而不包含 B2(i)中的任何错误时,才可以使用补丁 i。补丁 i 将修复软件中的某些错误 F1(i),而同时加入另一些错误 F2(i)。另外,每个补丁都耗费一定的时间。 试设计一个算法,利用公司提供的 m 个补丁程序将原软件修复成一个没有错误的软件,并使修复后的软件耗时最少。 

虽然是网络流24题,但是这题好像应该用最短路来做。

把20个bug状态压缩成二进制表示,然后跑Dijkstra最短路即可。

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> pii;
const int N=110;
const int INF=0x3f3f3f3f;
int n,m;
struct bug{
    int tim;
    char p[22],q[22];
}a[N];

bool check(int now,int k) {
    for (int i=0;i<m;i++)
        if (a[k].p[i]=='+' && !(now&(1<<i)) || a[k].p[i]=='-' && (now&(1<<i))) return 0;
    return 1;    
}

int change(int now,int k) {
    for (int i=0;i<m;i++) {
        if (a[k].q[i]=='-') now=now&(~(1<<i));
        if (a[k].q[i]=='+') now=now|(1<<i);
    }
    return now;
}

int d[1<<22];
priority_queue<pii> q;
int Dijkstra() {
    memset(d,0x3f,sizeof(d));
    d[(1<<m)-1]=0;
    q.push(make_pair(0,(1<<m)-1));
    while (!q.empty()) {
        pii x=q.top(); q.pop();
        if (d[x.second]!=-x.first) continue;
        for (int i=1;i<=n;i++)
            if (check(x.second,i)) {
                int y=change(x.second,i);
                if (d[x.second]+a[i].tim<d[y]) {
                    d[y]=d[x.second]+a[i].tim;
                    q.push(make_pair(-d[y],y));
                }
            }
    }
    return d[0]==INF ? 0 : d[0];
}

int main()
{
    scanf("%d%d",&m,&n);
    for (int i=1;i<=n;i++) scanf("%d%s%s",&a[i].tim,&a[i].p,&a[i].q);
    
    cout<<Dijkstra()<<endl;
    return 0;
} 

 

转载于:https://www.cnblogs.com/clno1/p/10709254.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值