RT,第 9 个点 WA 了,最短路长度错误/yun
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<ctime>
#include<cmath>
#include<iomanip>
#include<string>
#include<cstring>
#include<set>
#include<stack>
#include<queue>
#include<bitset>
using namespace std;
namespace IO{
template<typename T>inline void read(T &x){
x=0;
char ch=getchar();
bool flag=0;
while(ch<'0'||ch>'9') flag=flag||(ch=='-'),ch=getchar();
while(ch>='0'&&ch<='9') x=x*10+(ch^'0'),ch=getchar();
if(ch!='.'){
x=flag?-x:x;
return;
}
double Base=0.1;
while(ch<'0'||ch>'9') ch=getchar();
while(ch>='0'&&ch<='9') x=x+Base*(ch^'0'),Base/=10.0,ch=getchar();
x=flag?-x:x;
}
template<typename T>void prt(T x){
if(x>9) prt(x/10);
putchar(x%10+'0');
}
template<typename T>inline void put(char ch,T x){
if(x<0) putchar('-'),x=-x;
prt(x);
putchar(ch);
}
const int DM[10]={1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};
inline void putd(char ch,double x,int w){
if(x<0) putchar('-'),x=-x;
if(!w){
put(ch,(int)(x+0.5));
return;
}
int prex=(int)x;
x-=(int)x;
x*=DM[w];
x+=0.5;
int nowx=(int)x,now=0;
if(nowx>=DM[w]) nowx=0,prex++;
put('.',prex);
int xx=nowx;
if(!xx) now=1;
else while(xx) xx/=10,now++;
now=w-now;
while(now--) putchar('0');
put(ch,nowx);
}
inline void putstr(string s){
for(int i=0;i<s.length();i++) putchar(s[i]);
}
}
using namespace IO;
#define M 6000005
#define N 500100
#define Maxn 100005
#define hshmod 10000000007
#define ull unsigned long long
#define hshbase 2
#define khshbase 13
#define khshmod 193872937
ull bs[N],kb[N];
struct edge{
int v,nxt,w;
}e[N<<1];
int n,m,head[N],cnt,S,T,rt[N];
inline void add(int u,int v,int w){
e[++cnt]=(edge){v,head[u],w},head[u]=cnt;
}
inline ull mul(ull x,ull y,ull mod){
return x*y%mod;
}
inline ull add(ull x,ull y,ull mod){
return x+y>=mod?x+y-mod:x+y;
}
struct SegmentTree{
int idx=0;
struct node{
int ls,rs,siz;
//左右儿子,1的个数
ull hsh;
ull key;//答案和哈希
inline bool operator==(const node &b)const{
return siz==b.siz&&hsh==b.hsh&&key==b.key;
}
//hsh值
}t[M];//左边(下标小的)是低位,右边是高位
#define lc(x) t[x].ls
#define rc(x) t[x].rs
inline void init(){
bs[0]=kb[0]=1;
for(int i=1;i<=Maxn;i++)
bs[i]=mul(bs[i-1],hshbase,hshmod),kb[i]=mul(kb[i],khshbase,khshmod);
}
inline void push_up(int x){
t[x].siz=t[lc(x)].siz+t[rc(x)].siz;
t[x].hsh=add(t[lc(x)].hsh,t[rc(x)].hsh,hshmod);
t[x].key=add(t[lc(x)].key,t[rc(x)].key,(ull)khshmod);
}
int build(int l,int r,int val){//新建一个全0或全1的树
int x=++idx;
if(l==r){
t[x].hsh=mul(bs[l],val,hshmod);
t[x].key=mul(kb[l],val,khshmod);
t[x].siz=val;
return x;
}
int mid=l+r>>1;
lc(x)=build(l,mid,val),rc(x)=build(mid+1,r,val);
push_up(x);
return x;
}
int query(int x,int l,int r,int ql,int qr){//查询区间内有多少个1
if(ql<=l&&qr>=r) return t[x].siz;
int mid=l+r>>1,res=0;
if(ql<=mid) res+=query(lc(x),l,mid,ql,qr);
if(qr>mid) res+=query(rc(x),mid+1,r,ql,qr);;
return res;
}
int getpos(int x,int l,int r,int pos){//找到当前位置右边第一个0的位置
//此函数用于找到全1段的终点(处理进位)
if(l==r) return l;
int mid=l+r>>1;
if(pos>mid) return getpos(rc(x),mid+1,r,pos);
if(query(lc(x),l,mid,pos,mid)==mid-pos+1/*如果左边剩下的位置都是1*/) return getpos(rc(x),mid+1,r,pos);
return getpos(lc(x),l,mid,pos);
}
int update(int pre,int l,int r,int pos){//在pre版本基础上单点赋值为1
int x=++idx;
t[x]=t[pre];
if(l==r){
t[x].siz=1;
t[x].hsh=bs[l];
t[x].key=kb[l];
return x;
}
int mid=l+r>>1;
if(pos<=mid) lc(x)=update(lc(pre),l,mid,pos);
else rc(x)=update(rc(pre),mid+1,r,pos);
push_up(x);
return x;
}
int move(int x,int y,int l,int r,int ql,int qr){//区间赋值为0
if(qr<l||ql>r) return x;
if(ql<=l&&qr>=r) return y;
int mid=l+r>>1;
int now=++idx;
lc(now)=move(lc(x),lc(y),l,mid,ql,qr);
rc(now)=move(rc(x),rc(y),mid+1,r,ql,qr);
push_up(now);
return now;
}
int Add(int root,int val){//root版本加上2^val
int pos=getpos(root,0,Maxn,val);
int now=update(root,0,Maxn,pos);
if(pos!=val) now=move(now,rt[0],0,Maxn,val,pos-1);
return now;
}
int compare(int x,int y,int l,int r){//查询x是否小于等于y
if(l==r) return t[x].siz<=t[y].siz;
int mid=l+r>>1;
if(t[rc(x)]==t[rc(y)]) return compare(lc(x),lc(y),l,mid);
else return compare(rc(x),rc(y),mid+1,r);
}
}s;
struct left_tree{
int siz,root,idx;
struct node{
//当前点,权值(线段树的根),左右儿子,深度
int x,rt,ls,rs,dep;
}t[N];
#define lc(x) t[x].ls
#define rc(x) t[x].rs
int merge(int x,int y){//左偏树合并
if(!x||!y) return x|y;
if(s.compare(t[y].rt,t[x].rt,0,Maxn)) swap(x,y);
rc(x)=merge(rc(x),y);
if(t[rc(x)].dep>t[lc(x)].dep) swap(lc(x),rc(x));
t[x].dep=t[rc(x)].dep+1;
return x;
}
inline void push(int _x,int _rt){
siz++;
t[++idx]=(node){_x,_rt,0,0,0};
root=merge(root,idx);
}
inline void pop(){
siz--;
root=merge(lc(root),rc(root));
}
inline int top(){
return t[root].x;
}
inline bool empty(){
return siz==0;
}
}q;
bool vis[N];
int dis[N],pre[N],st[N],tp;
inline void dijkstra(){
int inf=s.build(0,Maxn,1);//初始一个极大值
for(int i=1;i<=n;i++) rt[i]=inf;
rt[0]=rt[S]=s.build(0,Maxn,0);//起点赋成0
q.push(S,rt[S]);
while(!q.empty()){
int x=q.top();
q.pop();
if(vis[x]) continue;
vis[x]=1;
for(int i=head[x];i;i=e[i].nxt){
int v=e[i].v;
if(vis[v]) continue;
int trans=s.Add(rt[x],e[i].w);
if(s.compare(rt[v],trans,0,Maxn)) continue;
rt[v]=trans,pre[v]=x;
q.push(v,rt[v]);
}
}
if(rt[T]==inf) return put('\n',-1),void();
put('\n',s.t[rt[T]].hsh%hshmod);
for(int x=T;x!=S;x=pre[x]) st[++tp]=x;
st[++tp]=S;
put('\n',tp);
while(tp) put(' ',st[tp--]);
}
int main(){
read(n),read(m);
s.init();
for(int i=1,u,v,w;i<=m;i++) read(u),read(v),read(w),add(u,v,w),add(v,u,w);
read(S),read(T);
dijkstra();
return 0;
}