输出路径是正确的,但是最短路的长度是错的。若在输出路径时统计最短路长度,那么可以过第九个点,但是无法过第十个点。
#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;
}