1. 程式人生 > >洛谷2761[軟體補丁問題

洛谷2761[軟體補丁問題

題目連結:軟體補丁問題

這一題還是能看出是網路流的,但是狀壓+spfa更為方便(因為就算硬上網路流的話流量基本上都是1)

直接將題目中所給的四種狀態狀態壓縮,即一開始的狀態為全1(全部都是bug),目標狀態是0

注意位運算的優先順序

#include<iostream>
#include<string>
#include<string.h>
#include<stdio.h>
#include<algorithm>
#include<math.h>
#include<vector>
#include<queue>
#include<map>
using namespace std;
#define maxd 1e9+7
int n,m,b1[120],b2[120],p1[120],p2[120],t[120],dis[2200000];
bool vis[2200000];
queue<int> q;

int read()
{
    int x=0,f=1;char ch=getchar();
    while ((ch<'0') || (ch>'9')) {if (ch=='-') f=-1;ch=getchar();}
    while ((ch>='0') && (ch<='9')) {x=x*10+(ch-'0');ch=getchar();}
    return x*f;
}

void init()
{
    n=read();m=read();int i,j;
    for (i=1;i<=m;i++)
    {
        char s[120];t[i]=read();
        scanf("%s",s);int tmp=1;
        for (j=0;j<n;j++)
        {
            if (s[j]=='+') b1[i]|=tmp;
            else if (s[j]=='-') b2[i]|=tmp;
            tmp<<=1;
        }
        scanf("%s",s);tmp=1;
        for (j=0;j<n;j++)
        {
            if (s[j]=='-') p1[i]|=tmp;
            else if (s[j]=='+') p2[i]|=tmp;
            tmp<<=1;
        }
    }
    //for (i=1;i<=n;i++) cout << b1[i] << " " << b2[i] << " " << p1[i] << " " << p2[i] << endl;
}

void spfa()
{
    int now=(1<<n)-1,i;
    memset(vis,0,sizeof(vis));
    for (i=0;i<=now;i++) dis[i]=maxd;
    dis[now]=0;vis[now]=1;q.push(now);
    while (!q.empty())
    {
        int u=q.front();q.pop();vis[u]=0;
        //cout << u << " " << dis[u] << endl;
        for (i=1;i<=m;i++)
        {
            if (((u&b1[i])==b1[i]) && ((u&b2[i])==0))
            {
                int v=(u&(~p1[i]))|p2[i];//cout << v << endl;
                //cout << v << " " << dis[v] << endl;
                if (u==v) continue;
                if (dis[v]>dis[u]+t[i])
                {
                    dis[v]=dis[u]+t[i];
                    if (!vis[v])
                    {
                        vis[v]=1;q.push(v);//cout << v << endl;
                    }
                }
            }
        }
    }
    if (dis[0]==maxd) printf("0");else printf("%d",dis[0]);
}

int main()
{
    init();
    spfa();
    return 0;
}