[最短路][二进制][Code+#4] Luogu P4366 最短路

运用了按位异或的玄妙性质来减小建边量

eg. \((001)_2 \rightarrow (100)_2 = (001)_2 \rightarrow (000)_2 \rightarrow (100)_2\)

这样我们在额外建边时只需建 \(i \rightarrow i \ XOR \ 2^k\)

注意处理 0 号节点,因为有可能经过 0 号节点 不然会过不了样例并 AC 本题

# include <iostream>
# include <cstdio>
# include <queue>
# define MAXN 100005
# define MAXM 7000005
// # define MAXN 105
// # define MAXM 105

using namespace std;

template<typename T>
T rd(){
	T fl = 1, x = 0;
	int ch = getchar();
	for(	;!isdigit(ch); ch = getchar()){
		if(ch == '-'){
			fl = -1;
		}
	}
	for(	; isdigit(ch); ch = getchar()){
		x = x * 10 + ch - '0';
	}
	return fl * x;
}

//
struct edge{
	int u, v, next, w;
}e[MAXM<<1];
int hd[MAXM<<1], cntE;

void AddE(int u, int v, int w){
	e[++cntE].u = u, e[cntE].v = v, e[cntE].w = w, e[cntE].next = hd[u], hd[u] = cntE;
}

//
struct node{
	int id, dis;
	bool operator > (const node that) const{
		return this->dis > that.dis;
	}
	bool operator < (const node that) const{
		return this->dis < that.dis;
	}
};

int dis[MAXN], vis[MAXN];

void Dij(int from, int lim){
	priority_queue<node, vector<node>, greater<node> >Q;
	
	for(int i = 0; i <= lim; i++){
		dis[i] = 1<<25, vis[i] = 0;
	} // 这里注意有可能会有从 0 出来的边

	dis[from] = 0;

	Q.push((node){from, dis[from]});

	while(!Q.empty()){
		node now = Q.top(); Q.pop();

		if(vis[now.id]){
			continue;
		}

		vis[now.id] = 1;

		for(int i = hd[now.id]; i; i = e[i].next){
			if(dis[now.id] + e[i].w < dis[e[i].v]){
				dis[e[i].v] = dis[now.id] + e[i].w;

				Q.push((node){e[i].v, dis[e[i].v]});
			}
		}
	}
}

//
int main(){
	int n, m, c;

	n = rd<int>(), m = rd<int>(), c = rd<int>();

	// // 处理加边
	
	for(int i = 0; i <= n; i++){
		for(int j = 0, to; j <= 20; j++){
			to = i ^ (1<<j);
			if(to <= n){
				AddE(i, to, c * (1<<j));
				// AddE(to, i, c * (1<<j));
			}
		}
	} // 注意有可能会连到 0 位置,所以外层的遍历要从 0 开始
	
	// // 处理加边

	for(int i = 1, u, v, w; i <= m; i++){
		u = rd<int>(), v = rd<int>(), w = rd<int>();
		AddE(u, v, w);
	}

	int from, to;

	from = rd<int>(), to = rd<int>();

	Dij(from, n);

	cout<<dis[to];

	return 0;
}



猜你喜欢

转载自www.cnblogs.com/Foggy-Forest/p/13402943.html