uva-658

https://vjudge.net/problem/UVA-658

思路:把每个bug的状态用2进制表示,把每个状态看成点,每个转化的过程看成边,由于补丁比较少,可以不建图直接暴力搜边就vans,dijkstra就行;

#include<iostream>
#include<iomanip>
#include<cstring>
#include<sstream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<stdlib.h>
#include<string>
#include<queue>
#include<vector>
#include<map>
#include<set>
#include<stack>
//#include<bits/stdc++.h>
#define _for(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
typedef long long ll;
const int mod =1e6+7;
double esp=1e-6;
int INF =0x3f3f3f3f;
//const int inf = 1<<28;
const int MAXN=200000+10;
const int inf=0x3f3f3f3f;
char be[110][25],af[110][25];
int vis[1<<20],d[1<<20],t[110],n,m;
struct node
{
    int bug,dist;
    bool operator < (const node &p)const
    {
        return dist>p.dist;
    }
};
int dijkstar()
{
    for(int i=0;i<(1<<n);i++)
    {
        d[i]=INF;
        vis[i]=0;
    }
    priority_queue<node> Q;
    Q.push((node){(1<<n)-1,0});
    d[(1<<n)-1]=0;
    while(!Q.empty())
    {
        node x=Q.top();
        Q.pop();
        if(x.bug==0)return x.dist;
        if(vis[x.bug])continue;
        vis[x.bug]=1;
        for(int i=0;i<m;i++)
        {
            bool f=1;
            for(int j=0;j<n;j++)
            {
                if(be[i][j]=='-'&&(x.bug&(1<<j))){f=0;break;}
                if(be[i][j]=='+'&&!(x.bug&(1<<j))){f=0;break;}
            }
            if(!f)continue;
            node next;
            next.bug=x.bug;
            next.dist=x.dist+t[i];
            for(int j=0;j<n;j++)
            {
                if(af[i][j]=='+')next.bug |= (1<<j);
                if(af[i][j]=='-')next.bug &= ~(1<<j);
            }
            if(next.dist<d[next.bug])
            {
                d[next.bug]=next.dist;
                Q.push(next);
            }
        }
    }
    return -1;
}
int main()
{
    int Case=0;
    while(scanf("%d%d",&n,&m)&&n&&m)
    {
        for(int i=0;i<m;i++)
        {
            scanf("%d%s%s",&t[i],be[i],af[i]);
        }
        int ans=dijkstar();
        printf("Product %d\n",++Case);
        if(ans<0)printf("Bugs cannot be fixed.\n\n");
        else printf("Fastest sequence takes %d seconds.\n\n",ans);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/kayiko/p/12332229.html