BZOJ1097【状压DP】

/* I will wait for you */

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <algorithm>
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <deque>
#include <set>
#include <map>
#include <string>
#define make make_pair
#define fi first
#define se second

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;

const int maxn =1500010;
const int maxm = 1010;
const int maxs = 26;
const int inf = 0x3f3f3f3f;
const int P = 1000000007;
const double error = 1e-9;

inline int read() {
	int x = 0, f = 1; char ch = getchar();
	while (ch < '0' || ch > '9') f = (ch == '-' ? -1 : 1), ch = getchar();
	while (ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar();
	return x * f;
}

struct edge {
	int v, w, next;
} e[maxn];

int n, m, k, cnt, head[maxn], d[maxn], vis[maxn],q[maxn];
int bin[maxs], must[maxs], dis[maxs][maxs], f[maxn][maxs];

void insert(int u, int v, int w) {
	e[cnt] = (edge) {v, w, head[u]}; head[u] = cnt++;
	e[cnt] = (edge) {u, w, head[v]}; head[v] = cnt++;
}

void spfa(int s) {
	for (int i = 1; i <= n; i++) d[i] = inf, vis[i] = 0;
	
	int he = 1,ta = 1; 
	q[1] = s, d[s] = 0;
	
	while (he <= ta) {
		int u = q[he++];
		vis[u] = 0;
		
		for (int i = head[u]; i != -1; i = e[i].next) {
			int v = e[i].v;
			if (d[u] + e[i].w < d[v]) {
				d[v] = d[u] + e[i].w;
				if (!vis[v]) vis[v] = 1, q[++ta] = v;
			}
		}
	}
	
	for (int i = 1; i <= k + 1; i++) dis[s][i] = d[i];
	
	dis[s][0] = d[n];
}

void init() {
	for (int i = 0; i < bin[k]; i++)
		for (int j = 1; j <= k + 1; j++)
			if(f[i][j] != -1)
				for (int t = 2; t <= k + 1 ; t++) {
					int v = i | bin[t - 2];
					if((i & must[t]) == must[t])
						if(f[v][t] > f[i][j] + dis[j][t] || f[v][t] == -1)
							f[v][t] = f[i][j] + dis[j][t];
				}
}

int main() {
	n=read(), m=read(), k=read();
	
	bin[0] = 1;
	for (int i = 1; i < maxs; i++) bin[i] = bin[i - 1] << 1;
	
	memset(head, -1, sizeof head);
	for (int i = 0; i < m; i++) {
		int u=read(), v=read(), w=read();
		insert(u, v, w);
	}
	
	for (int i = 1; i <= k + 1 ; i++) spfa(i);
	
	int q = read();
	
	while (q--) {
		int u = read(), v = read();
		must[v] |= bin[u - 2];
	}
	
	memset(f, -1, sizeof f);
	f[0][1] = 0, init();
	
	int ans = inf;
	for (int i = 1; i <= k + 1; i++) 
		if (f[bin[k] - 1][i] != -1)
			ans = min(ans, f[bin[k] - 1][i] + dis[i][0]);
	printf("%d\n",ans);
	
	return 0;
}

你可能感兴趣的:(BZOJ1097【状压DP】)