洛谷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;
}