先状态压缩,再求费用流,但耗内存太大,改变存边方式降低内存使用。
直接求最短路即可
//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