我【】这道题目!我♂要♂击♂剑♂!
  • 板块灌水区
  • 楼主vegetable_ste
  • 当前回复12
  • 已保存回复12
  • 发布时间2021/11/10 23:43
  • 上次更新2023/11/4 00:55:32
查看原帖
我【】这道题目!我♂要♂击♂剑♂!
305002
vegetable_ste楼主2021/11/10 23:43

P3489

将每一把剑状态压缩,跑最短路,怎么写都70pts,上次提问没人回复 qq_emoji: kk

#include <bits/stdc++.h>
using namespace std;
const int N = 210;
int n, m, p, k, sword[N], dist[N][10010];
bool vis[N][10010];
struct edge_node { int v, w, enemy; };
struct hero_node { int d, pos, sword; };
struct cmp {
	bool operator() (const hero_node& a, const hero_node& b) const {
		return a.d > b.d;
	}
};
vector<edge_node> e[N];
int ans = 0x3f3f3f3f;
#define mp(a, b, c) (hero_node){a, b, c}
void dijkstra() {
	memset(dist, 0x3f, sizeof dist);
	dist[1][sword[1]] = 0;
	priority_queue<hero_node, vector<hero_node>, cmp> Q;
	Q.push(mp(dist[1][sword[1]], 1, sword[1]));
	while(!Q.empty()) {
		int u = Q.top().pos, s = Q.top().sword; Q.pop();
		if(u == n) { ans = dist[u][s]; printf("%d\n", ans); return; }
		if(vis[u][s]) continue;
		vis[u][s] = true;
		for(unsigned i = 0; i < e[u].size(); i ++ ) {
			int v = e[u][i].v, w = e[u][i].w, en = e[u][i].enemy;
			int ns = s | sword[v];
			if((s | en) > s) continue;
			if(dist[v][ns] > dist[u][s] + w) {
				dist[v][ns] = dist[u][s] + w;
				Q.push(mp(dist[v][ns], v, ns));
			}
		}
	}
}
int main() {
	scanf("%d%d%d%d", &n, &m, &p, &k);
	for(int i = 1; i <= k; i ++ ) {
		int w, q; scanf("%d%d", &w, &q);
		for(int j = 1; j <= q; j ++ ) {
			int t; scanf("%d", &t);
			sword[w] |= 1 << (t - 1);
		}
	}
	for(int i = 1; i <= m; i ++ ) {
		int x, y, t, s, st = 0;
		scanf("%d%d%d%d", &x, &y, &t, &s);
		for(int j = 1; j <= s; j ++ ) {
			int tt; scanf("%d", &tt);
			st |= 1 << (tt - 1);
		}
		e[x].push_back((edge_node){y, t, st});
		e[y].push_back((edge_node){x, t, st});
	}
	dijkstra();
	for(int i = 0; i <= 10000; i ++ ) ans = min(ans, dist[n][i]);
	if(ans > 1e9) puts("-1");
//	else printf("%d\n", ans);
	return 0;
}
2021/11/10 23:43
加载中...