「网络流24题」 12. 软件补丁问题
「网络流24题」 12. 软件补丁问题
状压 DP,SPFA 转移。
没错,跟网络流没任何关系。
b1、b2、f1、f2 都用二进制存下来,第 i 位表示是否有这个错误。
然后从每位都是 1 到 0 跑一个 SPFA 就好了。
#include <cstdio>
#include <cstring>
#include <queue>
using std::queue;
const int MAXN=1<<21,MAXM=110,INF=0x3f3f3f3f;
bool exist[MAXN];
int n,m,w[MAXM],b1[MAXM],b2[MAXM],f1[MAXM],f2[MAXM],dis[MAXN];
void Initialize(void)
{
char s1[30],s2[30];
for(int i=1;i<=m;++i)
{
scanf("\n%d%s%s",&w[i],s1,s2);
for(int j=0,t;j<n;++j)
{
t=1<<j;
if(s1[j]=='+')
b1[i]|=t;
else if(s1[j]=='-')
b2[i]|=t;
if(s2[j]=='-')
f1[i]|=t;
else if(s2[j]=='+')
f2[i]|=t;
}
}
}
bool Skip(int i,int x)
{
return (x|b1[i])^x || x&b2[i];
}
bool SPFA(int S,int T)
{
queue<int> q;
memset(dis,0x3f,sizeof dis);
q.push(S);
exist[S]=true;
dis[S]=0;
while(!q.empty())
{
int u=q.front();
q.pop();
exist[u]=false;
for(int i=1,v;i<=m;++i)
if(!Skip(i,u))
{
v=(u^(u&f1[i]))|f2[i];
if(dis[v]>dis[u]+w[i])
{
if(!exist[v])
{
q.push(v);
exist[v]=true;
}
dis[v]=dis[u]+w[i];
}
}
}
return dis[T]^INF;
}
int main(int argc,char** argv)
{
scanf("%d %d",&n,&m);
Initialize();
printf("%d\n",SPFA((1<<n)-1,0) ? dis[0] : 0);
return 0;
}
谢谢阅读。