uva 658 It's not a Bug, it's a Feature! 最短路

题意:有一个软件有n个漏洞m个补丁,每种补丁都有一个修复时间,问你最短的修复时间修复完所有漏洞。

思路:很简单的最短路 建好图后直接套模板就好(凑个水题。。。)

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;

const int maxn = (1 << 20) + 10;
const int N = 25;
const int INF = 0x3f3f3f3f;

struct Edge{
    int u, d;
    Edge(int u = 0, int d = 0) : u(u), d(d) {}
    bool operator < (const Edge &rhs) const{
        return d > rhs.d;
    }
};

int n, m, t;
int bi[N], pow_[N];
int visit[maxn], dist[maxn];
char bug[N], new_bug[N];
vector<pair<int, int> > G[maxn];

void init(){
    pow_[0] = 1;
    for(int i = 1; i <= 21; i++)
        pow_[i] = pow_[i-1] * 2;
}

void build_path(int cur){
    if(cur == n){
        int u = 0, v = 0;
        for(int i = n - 1; i >= 0; i--){
            u += bi[i] * pow_[n-1-i];
            if(new_bug[i] == '+') v += pow_[n-1-i];
            else if(new_bug[i] == '0') v += bi[i] * pow_[n-1-i];
        }
        G[u].push_back(make_pair(v, t));
        //printf("%d to %d va %d\n", u, v, t);
        return;
    }
    if(bug[cur] == '-'){
        bi[cur] = 0;
        build_path(cur + 1);
        return;
    }
    if(bug[cur] == '+'){
        bi[cur] = 1;
        build_path(cur + 1);
        return;
    }
    bi[cur] = 0; build_path(cur + 1);
    bi[cur] = 1; build_path(cur + 1);
}

int dijkstra(){
    memset(visit, 0, sizeof(visit));
    memset(dist, INF, sizeof(dist));
    int s = (1 << n) - 1, t = 0;
    priority_queue<Edge> Q;
    Q.push(Edge(s, 0));
    dist[s] = 0;
    while(!Q.empty()){
        Edge cur = Q.top(); Q.pop();
        int u = cur.u;
        if(visit[u]) continue;
        visit[u] = 1;
        for(int i = 0; i < (int)G[u].size(); i++){
            int v = G[u][i].first;
            int d = G[u][i].second;
            if(dist[v] > dist[u] + d){
                dist[v] = dist[u] + d;
                Q.push(Edge(v, dist[v]));
            }
        }
    }
    return dist[t];
}

int cas = 0;

void solve(){
    for(int i = 0; i < (1 << n); i++) G[i].clear();
    for(int i = 0; i < m; i++){
        scanf("%d%s%s", &t, bug, new_bug);
        build_path(0);
    }
    int ans = dijkstra();
    printf("Product %d\n", ++cas);
    if(ans == INF)
        printf("Bugs cannot be fixed.\n\n");
    else
        printf("Fastest sequence takes %d seconds.\n\n", ans);
}

int main()
{
    init();
    while(scanf("%d%d", &n, &m) && n) solve();
    return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值