WA第九个点求助
查看原帖
WA第九个点求助
219202
code_hunter楼主2021/6/3 08:43

输出路径是正确的,但是最短路的长度是错的。若在输出路径时统计最短路长度,那么可以过第九个点,但是无法过第十个点。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue> 

#define int long long//这题应该不用
//但我还是开了long long。
#define For(i,a,b) for(int i = a ; i <= b ; i ++)
#define FoR(i,a,b) for(int i = a ; i >= b ; i --)
typedef long long ll;
ll MAX(ll x , ll y) {return (x > y) ? x : y;}
ll MIN(ll x , ll y) {return (x < y) ? x : y;}
const int MAXN = 1e5 + 543;
const int MAXM = 1e5 + 543;
const int MAXA = 1e5 + 543;
const int MO = 1e9 + 7;
const int hash_mod = 1e9 + 9; 
using namespace std;

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

int N , M , S , T;

int fa[MAXN];
int findfa(int x) {
	return fa[x] == x ? x : fa[x] = findfa(fa[x]);
} 
void meRge(int x , int y) {
	x = findfa(x);
	y = findfa(y);
	if (x == y)
		return;
	if (x > y) {
		x ^= y;
		y ^= x;
		x ^= y;
	} 
	fa[y] = x;
}
 
int h[MAXN] , nowe;
struct Edge{
	int u , v , w , next;
}e[MAXM << 1 | 1];
void addEdge(int u , int v , int w) {
	nowe ++;
	e[nowe].u = u;
	e[nowe].v = v;
	e[nowe].w = w;
	e[nowe].next = h[u];
	h[u] = nowe;
}

int hash_pwr[MAXA];
int pwr[MAXA];

int now;
struct Node{
	int hash_sum , sum;
	int l , r; 
}a[39 * MAXN];
int build (int l , int r) {
	int rt = ++ now;
	if (l == r)
		return rt;
	int mid = (l & r) + ((l ^ r) >> 1);
	a[rt].l = build(l , mid);
	a[rt].r = build(mid + 1 , r);
	return rt;
}
int modify(int o , int l , int r , int pos) {
	int rt = ++ now;
	a[rt].l = a[o].l , a[rt].r = a[o].r;
	if (l == r) {
		a[rt].hash_sum = hash_pwr[pos];
		a[rt].sum = pwr[pos];
		return rt;
	} 
	int mid = (l & r) + ((l ^ r) >> 1);
	if (pos <= mid)
		a[rt].l = modify(a[o].l , l , mid , pos);
	else
		a[rt].r = modify(a[o].r , mid + 1 , r , pos);
	a[rt].hash_sum = (a[a[rt].l].hash_sum + a[a[rt].r].hash_sum) % hash_mod;
	a[rt].sum = (a[a[rt].l].sum + a[a[rt].r].sum) % MO;
	return rt;
} 
int hash_query(int o , int l , int r , int ql , int qr) {
	if (ql <= l && r <= qr)
		return a[o].hash_sum;
	int mid = (l & r) + ((l ^ r) >> 1) , res = 0;
	if (ql <= mid)
		res = (res + hash_query(a[o].l , l , mid , ql , qr)) % hash_mod;
	if (qr > mid)
		res = (res + hash_query(a[o].r , mid + 1 , r , ql , qr)) % hash_mod;
	return res;
}
int query(int o , int l , int r , int ql , int qr) {
	if (ql <= l && r <= qr)
		return a[o].sum;
	int mid = (l & r) + ((l ^ r) >> 1) , res = 0;
	if (ql <= mid)
		res = (res + query(a[o].l , l , mid , ql , qr)) % MO;
	if (qr > mid)
		res = (res + query(a[o].r , mid + 1 , r , ql , qr)) % MO;
	return res;
}

void tree_cmp(int ctrv , int ctrc , int l , int r , int ql , int qr) {
	if (ql <= l && r <= qr) {
		a[ctrv] = a[ctrc];
		return;
	}
	int mid = (l & r) + ((l ^ r) >> 1);
	if (ql <= mid)
		tree_cmp(a[ctrv].l , a[ctrc].l , l , mid , ql , qr);
	if (qr > mid)
		tree_cmp(a[ctrv].r , a[ctrc].r , mid + 1 , r , ql , qr);
	a[ctrv].hash_sum = (a[a[ctrv].l].hash_sum + a[a[ctrv].r].hash_sum) % hash_mod;
	a[ctrv].sum = (a[a[ctrv].l].sum + a[a[ctrv].r].sum) % MO;
}

int findpos(int o , int val) {
	int l = val , r = MAXA - 2 , mid;
	while (l + 1 < r) {
		mid = (l & r) + ((l ^ r) >> 1);
		if ((hash_query(o , 0 , MAXA - 1 , val , mid) == (hash_pwr[mid + 1] - hash_pwr[val] + hash_mod) % hash_mod) &&
			 query(o , 0 , MAXA - 1 , val , mid) == (pwr[mid + 1] - pwr[val] + MO) % MO)
			l = mid;
		else
			r = mid;
	}
	if ((hash_query(o , 0 , MAXA - 1 , val , r) == (hash_pwr[r + 1] - hash_pwr[val] + hash_mod) % hash_mod) &&
		 query(o , 0 , MAXA - 1 , val , r) == (pwr[r + 1] - pwr[val] + MO) % MO)
		return r + 1;
	else
		return l + 1;
}

int add(int o , int val) {
	if (!query(o , 0 , MAXA - 1 , val , val) || !hash_query(o , 0 , MAXA - 1 , val , val)) {
		return modify(o , 0 , MAXA - 1 , val);
	} 
	int pos = findpos(o , val);
	int res = modify(o , 0 , MAXA - 1 , pos);
	tree_cmp(res , 0 , 0 , MAXA - 1 , val , pos - 1);
	return res;
}
struct roots{
	int ord;
	bool operator < (const roots &b) const {
		int l = 0 , r = MAXA - 1 , cm = ord , cp = b.ord;	
		while (l < r) {
			int mid = (l & r) + ((l ^ r) >> 1);
			if ((a[cm].hash_sum) % hash_mod != (a[cp].hash_sum) % hash_mod ||
				(a[cm].sum) % MO != (a[cp].sum) % MO) {
				if ((a[a[cm].r].hash_sum) % hash_mod != (a[a[cp].r].hash_sum) % hash_mod ||
					(a[a[cm].r].sum) % MO != (a[a[cp].r].sum) % MO) {
					cm = a[cm].r;
					cp = a[cp].r;
					l = mid + 1;
				}
				else {
					cm = a[cm].l;
					cp = a[cp].l;
					r = mid;
				}
			}
			else
				return false;
		}
		return (a[cm].hash_sum) % hash_mod != 0 && (a[cp].hash_sum) % hash_mod == 0;
	}
}t[MAXM];
int en;
priority_queue <pair<roots , int> > q;
int dis[MAXN] , frm[MAXN];
bool vis[MAXN];

void dijkstra() {
	t[en ++].ord = build(0 , MAXA - 1);
	dis[S] = 0;
	q.push(make_pair(t[0] , S));
	while (!q.empty()) {
		int x = q.top().second;
		q.pop();
		if (vis[x])
			continue;
		vis[x] = true;
		for (int i = h[x] ; i ; i = e[i].next) {
			const int &v = e[i].v;
			const int &w = e[i].w;
			if (vis[v])
				continue;
			t[en].ord = add(t[dis[x]].ord , w);
			en ++;
			if (dis[v] == -1 || t[dis[v]] < t[en - 1]) {
				dis[v] = en - 1;
				frm[v] = x;
				q.push(make_pair(t[dis[v]] , v));
			}
		}
	}
}
int cnt = 0;
void Print(int x) {
	if (x == 0)
		return;
	if (x == S) {
		printf ("%lld\n" , cnt + 1);
		printf ("%lld " , x);
		return;
	}
	cnt ++;
	Print(frm[x]);
	printf ("%lld " , x); 
}

signed main() {
	memset(dis , -1 , sizeof(dis));
	pwr[0] = hash_pwr[0] = 1;
	For (i , 1 , MAXA - 1)
		hash_pwr[i] = (hash_pwr[i - 1] << 1) % hash_mod;
	For (i , 1 , MAXA - 1)
		pwr[i] = (pwr[i - 1] << 1) % MO;
	N = Read();
	For (i , 1 , N)	fa[i] = i;
	M = Read();
	For (i , 1 , M) {
		int u = Read();
		int v = Read();
		int x = Read();
		addEdge(u , v , x);
		addEdge(v , u , x);
		meRge(u , v);
	}
	S = Read();
	T = Read();
	if (findfa(S) != findfa(T)) {
		printf ("-1\n");
		return 0;
	}
	dijkstra();
	printf ("%lld\n" , a[t[dis[T]].ord].sum);
	Print(T);
	printf ("\n");
	return 0;
}


2021/6/3 08:43
加载中...