[CodePlus 2018]最短路

題目

傳送門 to usOJ

題目概要
有一個 NN 個點的圖,有 MM 條有向邊直接讀入。其次,任意兩個點 i,ji,j 之間有權值爲 c×(ij)c\times(i\oplus j) 的無向邊。

現求 AABB 的最短路。

數據範圍與約定
N105,M5×105N\le 10^5,M\le 5\times 10^5 ,邊權和 cc 均不超過 100100

思路

你以爲跟 cc 有關?那就完全錯了。事實上,我們可以將 iji\oplus j 拆成很多步,即

ij=(ia1)+(a1a2)++(akj)i\oplus j=(i\oplus a_1)+(a_1\oplus a_2)+\cdots+(a_k\oplus j)

其中 t,s.t. 2t=ap\exist t,\text{s.t. }2^t=a_p 。所以我們直接將 iii2ti\oplus 2^t 連邊,跑最短路,結束。

代碼

#include <cstdio>
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
typedef long long int_;
int readint(){
	int a = 0; char c = getchar(), f = 1;
	for(; c<'0'||c>'9'; c=getchar())
		if(c == '-') f = -f;
	for(; '0'<=c&&c<='9'; c=getchar())
		a = (a<<3)+(a<<1)+(c^48);
	return a*f;
}

const int MaxN = 100005;
const int_ infty = (1ll<<62)-1;
struct Edge{
	int to, nxt, val;
	Edge(int T=0,int N=0,int V=0){
		to = T, nxt = N, val = V;
	}
} edge[60*MaxN];
int cntEdge, head[MaxN];
void addEdge(int a,int b,int c){
	edge[cntEdge] = Edge(b,head[a],c);
	head[a] = cntEdge ++;
}

struct State{
	int x; int_ dis;
	State(int X=0,int_ D=0):x(X),dis(D){}
	bool operator < (const State &that) const {
		return dis > that.dis;
	}
};
priority_queue< State > pq;
int_ dis[MaxN]; int n, m, C;
void dijkstra(int from){
	for(int i=0; i<=n; ++i)
		dis[i] = infty;
	dis[from] = 0;
	pq.push(State(from,0));
	while(not pq.empty()){
		int x = pq.top().x;
		if(dis[x] < pq.top().dis){
			pq.pop(); continue;
		} pq.pop();
		for(int i=head[x]; ~i; i=edge[i].nxt)
			if(dis[edge[i].to] > dis[x]+edge[i].val){
				dis[edge[i].to] = dis[x]+edge[i].val;
				pq.push(State(edge[i].to,dis[edge[i].to]));
			}
	}
}

int main(){
	n = readint(), m = readint();
	C = readint();
	for(int i=1; i<=n; ++i){
		head[i] = -1;
		for(int j=1; j<=n; j<<=1)
			if((i^j) <= n)
				addEdge(i,i^j,j*C);
	}
	head[0] = -1;
	for(int j=1; j<=n; j<<=1)
		addEdge(0,j,j*C);
	for(int a,b; m; --m){
		a = readint(); b = readint();
		addEdge(a,b,readint());
	}
	int A = readint();
	dijkstra(A);
	A = readint();
	printf("%lld\n",dis[A]);
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章