蒟蒻疑问:看不懂题解
查看原帖
蒟蒻疑问:看不懂题解
747401
dfs0ms楼主2023/1/14 11:23

这是蒟蒻的 AC 代码,吸氧了:

蒟蒻有一个问题,上面的代码是看题解的(所以 AC,思路是节点 u 和所有 边权2k2^k 的节点连,但是为什么不是和所有 编号2k2^k 的节点连呢?


如果将所有节点包含 00nn,都和所有编号为 2k2^k 的节点连,可以保证一定覆盖了所有路径,因为:

比如两个节点 ab,可以保证对于任意的 2k2^k,满足 aa xorxor 2k2^k ++ 2k2^k xorxor bb == aa xorxor bb 啊(?

#include <cstdio>
#include <queue>
using namespace std;
const int N = 100010;
const int INF = 1e8;

int n, m, c, s, t;
struct node { int v, w; }; vector<node> G[N];

void add()
{
	scanf("%d%d%d", &n, &m, &c);
	for (int i = 1, u, v, w; i <= m; i++)
		scanf("%d%d%d", &u, &v, &w), G[u].push_back(node{ v,w });
	scanf("%d%d", &s, &t);
	for (int i = 0; i <= n; i++) /// 考虑 0 号节点
	{
		for (int k = 1; k <= n; k <<= 1)
		{
		/// i 花费 k 到 i ^ k
		    if ((i ^ k) > n) continue;
		    G[i].push_back(node{ i ^ k, k * c });
		}
	}
}
struct cmp {
	bool operator()(node a, node b) { return a.w > b.w; }
};
priority_queue<node, vector<node>, cmp> Q;
int dis[N];
bool vis[N]; /// 是否已经确定为最短路
void dijkstra()
{
	for (int i = 0; i <= n; i++) dis[i] = INF; dis[s] = 0; vis[s] = true;
	for (int i = 0; i < G[s].size(); i++)
		dis[G[s][i].v] = G[s][i].w, Q.push(G[s][i]);
	while (!Q.empty())
	{
		int u = Q.top().v;
		if (vis[u]) { Q.pop(); continue; }
		else { dis[u] = Q.top().w; Q.pop(); vis[u] = true; }
		for (int i = 0; i < G[u].size(); i++)
		{
			int v = G[u][i].v, w = G[u][i].w;
			if (vis[v]) continue;
			if (dis[v] > dis[u] + w)
				dis[v] = dis[u] + w, Q.push(node{ v,dis[v] });
		}
	}

}
int main()
{
	add();
	dijkstra();
	printf("%d", dis[t]);
	return 0;
}

这里是未 AC 代码:

/// 只用建 u 节点和 2 ^ k 的道路即可
#include <cstdio>
#include <queue>
using namespace std;
const int N = 100010;
const int INF = 1e8;

int n, m, c, s, t;
struct node { int v, w; }; vector<node> G[N];

void add()
{
	scanf("%d%d%d", &n, &m, &c);
	for (int i = 1, u, v, w; i <= m; i++)
		scanf("%d%d%d", &u, &v, &w), G[u].push_back(node{ v,w });
	scanf("%d%d", &s, &t);
	for (int i = 0; i <= n; i++)
	{
		for (int k = 1; k <= n; k <<= 1)
		{
		/// 从 i 到 k,从 k 到 i
			G[i].push_back(node{ k,(i ^ k) * c });
			G[k].push_back(node{ i,(i ^ k) * c });
		}
	}
}
struct cmp {
	bool operator()(node a, node b) { return a.w > b.w; }
};
priority_queue<node, vector<node>, cmp> Q;
int dis[N];
bool vis[N]; /// 是否已经确定为最短路
void dijkstra()
{
	if (s == t) return;
	for (int i = 0; i <= n; i++) dis[i] = INF; dis[s] = 0; vis[s] = true;
	for (int i = 0; i < G[s].size(); i++)
		dis[G[s][i].v] = G[s][i].w, Q.push(G[s][i]);
	while (!Q.empty())
	{
		int u = Q.top().v;
		if (vis[u]) { Q.pop(); continue; }
		else { dis[u] = Q.top().w; Q.pop(); vis[u] = true; }
		for (int i = 0; i < G[u].size(); i++)
		{
			int v = G[u][i].v, w = G[u][i].w;
			if (vis[v]) continue;
			if (dis[v] > dis[u] + w)
				dis[v] = dis[u] + w, Q.push(node{ v,dis[v] });
		}
	}

}
int main()
{
	add();
	dijkstra();
	printf("%d", dis[t]);
	return 0;
}
2023/1/14 11:23
加载中...