软件补丁问题(状态压缩 最短路)

先状态压缩,再求费用流,但耗内存太大,改变存边方式降低内存使用。

直接求最短路即可

//http://www.cnblogs.com/IMGavin/
#include <iostream>
#include <stdio.h>
#include <cstdlib>
#include <cstring>
#include <queue>
#include <vector>
#include <map>
#include <stack>
#include <set>
#include <bitset>
#include <algorithm>
using namespace std;

typedef long long LL;
#define gets(A) fgets(A, 1e8, stdin)
const int INF = 0x3F3F3F3F, N = 2000008, M = 108;
int n, m;
int b1[M], b2[M], f1[M], f2[M], cost[M];

const double EPS = 1e-6;
int dis[N];
bool inq[N];

char str[1000];

int SPFA(int st, int des){
	memset(inq, 0, sizeof(inq));
	memset(dis, 0x3f, sizeof(dis));
	queue <int> q;
	q.push(st);
	dis[st] = 0;
	inq[st] = true;
	while(!q.empty()){
		int u = q.front();
		q.pop();
		inq[u] = false;
		for(int i = 0; i < m; i++){
			if(( (u & b1[i]) == b1[i]) && ( (u & b2[i]) == 0)){
				int v = u & (~f1[i]) | f2[i];
				if(dis[v] > dis[u] + cost[i]){
					dis[v] = dis[u] + cost[i];
					if(!inq[v]){
						inq[v] = true;
						q.push(v);
					}
				}

			}
		}
	}
	if(dis[des] >= INF){
			return 0;
	}
	return dis[des];
}

int main(){
	while(cin >> n >> m){
		memset(b1, 0, sizeof(b1));
		memset(b2, 0, sizeof(b2));
		memset(f1, 0, sizeof(f1));
		memset(f2, 0, sizeof(f2));

		int st = (1<<n) - 1, des = 0;
		for(int k = 0; k < m; k++){
			scanf("%d", &cost[k]);
			scanf("%s", str);
			for(int i = 0; i < n; i++){
				if(str[i] == ‘+‘){
					b1[k] |= (1 << i);
				}else if(str[i] == ‘-‘){
					b2[k] |= (1 << i);
				}
			}

			scanf("%s", str);
			for(int i = 0; i < n; i++){
				if(str[i] == ‘-‘){
					f1[k] |= (1 << i);
				}else if(str[i] == ‘+‘){
					f2[k] |= (1 << i);
				}
			}
		}
		printf("%d\n", SPFA(st, des));
	}

	return 0;
}

  

时间: 2024-10-14 12:38:30

软件补丁问题(状态压缩 最短路)的相关文章

uva 11280 状态压缩+最短路

题意:坐飞机从 a 地到 b 地 ,在最多停留s次时 , 最小花费是多少? 在题目给出的地点 , 是按从远到近给出的 , 并且给出的航班中 , 不会有从远地点到近地点的航班. 因此从这可以看出 , 题目给的图是一个DAG图 , 那么我们就能用toposort来找最短路. 注意: 会有重边 解法: 构造一个数组 d[i][j]  , 表示从开始点 s  到点 i , 在停留 j 次时的最小花费. 然后我们再求出这个图的toposort , 再求这个每一个点和其相邻点的距离. 代码: #includ

poj 3311 Hie with the Pie (状态压缩+最短路)

Hie with the Pie Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 4491   Accepted: 2376 Description The Pizazz Pizzeria prides itself in delivering pizzas to its customers as fast as possible. Unfortunately, due to cutbacks, they can affo

Light OJ 1316 A Wedding Party 最短路+状态压缩DP

题目来源:Light OJ 1316 1316 - A Wedding Party 题意:和HDU 4284 差不多 有一些商店 从起点到终点在走过尽量多商店的情况下求最短路 思路:首先预处理每两点之前的最短路 然后只考虑那些商店 个数小于15嘛 就是TSP问题 状态压缩DP搞一下 状态压缩姿势不对 有必要加强 #include <cstdio> #include <algorithm> #include <queue> #include <vector>

[luoguP2761] 软件补丁问题(状压最短路)

传送门 n <= 20 很小 所以可以状态压缩 然后因为可能存在环,所以不能DP 那么就用spfa找最短路 被位运算坑了,不清楚优先级一定要加括号 ——代码 1 #include <queue> 2 #include <cstdio> 3 #include <cstring> 4 #include <iostream> 5 #define M 301 6 #define N 4000001 7 8 int n, m; 9 int b1[M], b2[M

【网络流24题】软件补丁问题(最短路)

[网络流24题]软件补丁问题(最短路) 题面 COGS 题解 这题貌似和网络流没啥关系 因为错误很少 可以直接状压 然后利用位运算直接跑最短路就行了 #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<algorithm> #include<set> #include<map&

2010辽宁省赛E(Bellman_Ford最短路,状态压缩DP【三进制】)

#include<bits/stdc++.h>using namespace std;const int inf=0x3f3f3f3f;struct node{    int v,z,d,next;//存可以连接的点,用next存邻接表}a[10010];struct road{    int u,cnt,dis;//dis储存当前需要的钱数,即最短路算法里的权,u储存顶点,cnt储存组合数即状态压缩dp    road(int uu,int cntt,int diss)    {      

uva658 dijkstra+状态压缩

题目大意: 假定有n个潜在的bug和m个补丁,每个补丁用长为n的字符串表示.首先输入bug数目以及补丁数目.然后就是对m 个补丁的描述,共有m行.每行首先是一个整数,表明打该补丁所需要的时间.然后是两个字符串,地一个字符串 是对软件的描述,只有软件处于该状态下才能打该补丁该字符串的每一个位置代表bug状态(-代表该位置没bug,+代 表该位置有bug,0表示该位置无论有没有bug都可打补丁).然后第二个字符串是对打上补丁后软件状态的描述 -代表该位置上的bug已经被修复,+表示该位置又引入了一个

uva658(最短路径+隐式图+状态压缩)

题目连接(vj):https://vjudge.net/problem/UVA-658 题意:补丁在修正 bug 时,有时也会引入新的 bug.假定有 n(n≤20)个潜在 bug 和 m(m≤100) 个补丁,每个补丁用两个长度为 n 的字符串表示,其中字符串的每个位置表示一个 bug.第一 个串表示打补丁之前的状态("-" 表示该 bug 必须不存在,"+" 表示必须存在,0 表示无所 谓),第二个串表示打补丁之后的状态("-" 表示不存在,

P2761 软件补丁问题

P2761 软件补丁问题 思路 貌似不用网络流,直接状态压缩 用spfa跑最短路,直接判断是否能过 位运算太渣了,WA了好几发 代码 #include <bits/stdc++.h> using namespace std; const int N = 21, M = 101, inf = 0x3f3f3f3f; int read() { int x = 0, f = 1; char s = getchar(); for(; s > '9' || s < '0'; s = getc