[網絡流24題] 軟件補丁問題

Luogu2761
似乎這不是一道網絡流的題目qwq,發現n很小,於是我們可以考慮狀態壓縮,也只是220 種狀態,對於狀態a可以到達狀態b,則連接一條時間的邊。跑一遍spfa就行了
但是這題更加坑的是卡空間,我們發現一條一條邊建了之後空間會炸。於是乎用每次spfa時暴力枚舉m種補丁, 免去建邊的空間(傳說中的時間換空間2333)

    #include<iostream>
    #include<iomanip>
    #include<cmath>
    #include<algorithm>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    struct nodes{
        int f1,f2,b1,b2,t;
    }a[300]; 
    int n,m,maxnum;
    char b[300],f[300];
    bool vis[2000100];
    int head,tail,dist[2000100],dl[5000100],v;
    void spfa()
    {
        memset(dist,0x3f,sizeof(dist)); 
        dist[maxnum]=0;vis[maxnum]=1;
        head=tail=1;
        dl[tail]=maxnum;
        while(head<=tail)
        {
         v=dl[head];
        for(int i=1;i<=m;++i)
            if(((v&a[i].b2)==0)&&((v&a[i].b1)==a[i].b1))
            {
                int num=v^(a[i].f1&v)|a[i].f2;
                if(dist[num]>dist[v]+a[i].t)
                {
                    dist[num]=dist[v]+a[i].t;
                    if(!vis[num]) dl[++tail]=num,vis[num]=1;
                }
            }
        vis[dl[head++]]=false;
        }
        if(dist[0]==0x3f3f3f3f) cout<<0<<endl;
        else cout<<dist[0];
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        maxnum=(1<<n)-1;
        for(int i=1;i<=m;++i)
        {
            scanf("%d",&a[i].t);
            scanf("%s",b);
            for(int j=0;j<n;++j)
            if(b[j]=='+') a[i].b1|=(1<<j);
            else if(b[j]=='-') a[i].b2|=(1<<j);
            scanf("%s",f);
            for(int j=0;j<n;++j)
            if(f[j]=='-') a[i].f1|=(1<<j);
            else if(f[j]=='+') a[i].f2|=(1<<j);
        }
        spfa();
        return 0;   
    }
發佈了29 篇原創文章 · 獲贊 0 · 訪問量 5238
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章