【网络流 24 题】【Luogu P2761】 软件补丁问题

题目大意:

有一个长度为 \(n\) 的只包含 '-' 或 '+' 的字符串,刚开始全是 '+',还有 \(m\) 次操作,每次操作有一个时间 \(c\)、两个只包含 '-'、'+'、'0' 的 字符串\(A\) 和 字符串\(B\),如果字符串和 字符串\(A\) 相等(字符串\(A\) 中 '0' 的位置不算),那字符串就可以变为 字符串\(B\)(字符串\(A\) 中 '0' 的位置不算),每次操作要耗 \(c\)。问最少多少时间让字符串全变为 '-'。

正文:

因为 \(n\leq 20\), 所以可以使用状态压缩,'-' 和 '+' 分别用 '0' 和 '1' 来表示。根据原题我们可以用位运算来判断原字符串是否与字符串 \(A\) 相等:

if((u & b1[i]) == b1[i] && (u & b2[i]) == 0)

b1[i]b2[i] 都是原文提到的。)

还是根据原题可以将字符串变为 字符串\(B\)

((u | f1[i]) ^ f1[i]) | f2[i]

f1[i]f2[i] 也都是原文提到的。)

得到这些就可以用最短路解决本题了,我采用了 SPFA。

代码:

const int N = 110;

int n, m; 
int b1[N], b2[N], f1[N], f2[N], TiMe[N];
int dis[1 << 21];

inline void read(int &x) 
{
    char ch = getchar();
    while(ch < '0' || ch > '9')
		ch = getchar();
    x = ch - 48; ch = getchar();
    while(ch >= '0' && ch <= '9') 
	{
        x = x * 10 + (ch - 48);
        ch=getchar();
    }
}

queue <int> que;
bool vis[1 << 21];

void SPFA()
{
	memset(dis, 0x7f, sizeof dis);
	dis[(1 << n) - 1] = 0;
	que.push((1 << n) - 1);
	while (!que.empty())
	{
		int u = que.front();que.pop();
		for (int i = 1; i <= m; i++)
		{
			if((u & b1[i]) == b1[i] && (u & b2[i]) == 0)
			{
				int v = ((u | f1[i]) ^ f1[i]) | f2[i];
				if(dis[u] + TiMe[i] < dis[v])
				{
					dis[v] = dis[u] + TiMe[i];
					if(!vis[v])
					{
						que.push(v);
						vis[v] = 1;
					}
				}
			}
		}
		vis[u] = 0;
	}
}

int main()
{
//	freopen(".in", "r", stdin);
//	freopen(".out", "w", stdout);
	read(n), read(m);
	for (int i = 1; i <= m; i++)
	{
		read(TiMe[i]);
	    char ch = getchar();
	    while(ch != '+' && ch != '-' && ch != '0')
			ch = getchar();
		for(int j = 1; j <= n; ++j)
		{
			if(ch == '+')
				b1[i] += 1 << (j - 1);
			if(ch == '-')
				b2[i] += 1 << (j - 1);
			ch = getchar();	
		}
	    while(ch != '+' && ch != '-' && ch != '0')
			ch = getchar();
		for(int j = 1; j <= n; ++j)
		{
			if(ch == '-')
				f1[i] += 1 << (j - 1);
			if(ch == '+')
				f2[i] += 1 << (j - 1);
			ch = getchar();	
		}
	}
	SPFA();
	if (dis[0] == dis[(1<<21)-1]) puts("0");
	else printf("%d\n", dis[0]); 
    return 0;
}

posted @ 2020-03-29 23:58  Jayun  阅读(114)  评论(0编辑  收藏  举报