传送门
用可持久化线段树维护二进制数。
i
n
s
e
r
t
insert
insert的时候记录一下进位即可。
r
o
o
t
[
i
]
root[i]
root[i]表示
i
i
i号节点到根的距离的线段树。
#include<bits/stdc++.h>
#define lc(x) (T[x].l)
#define rc(x) (T[x].r)
#define mid ((l+r)>>1)
using namespace std;
const int maxn=1e5+10,mod=1e9+7,Log=120;
int n,m,s,t,u,v,w,mx,tot=1,ans=0,P[maxn+15],out[maxn];
int Head[maxn],Next[maxn<<1],V[maxn<<1],W[maxn<<1],cnt=0;
struct node{int l,r,sum;}T[maxn*Log];
inline int add(int x,int y){return x+y>=mod?x+y-mod:x+y;}
inline int mul(int x,int y){return (long long)x*y%mod;}
inline void add(int u,int v,int w){Next[++cnt]=Head[u],V[cnt]=v,W[cnt]=w,Head[u]=cnt;}
inline void pushup(int root,int l,int r){T[root].sum=add(T[lc(root)].sum,mul(T[rc(root)].sum,P[mid-l+1]));}
inline bool cmp(int x,int y,int l,int r){
if(l==r) return T[x].sum<T[y].sum;
return (T[rc(x)].sum==T[rc(y)].sum)?cmp(lc(x),lc(y),l,mid):cmp(rc(x),rc(y),mid+1,r);
}
struct Heap_node{
int id,root;
Heap_node(int ID=0,int ROOT=0){id=ID,root=ROOT;}
friend inline bool operator<(const Heap_node &a,const Heap_node &b){return !cmp(a.root,b.root,0,mx);}
};
inline int insert(int &now,int pre,int l,int r,int pos){
T[now=++tot]=T[pre];
if(l==r){T[now].sum^=1;return T[pre].sum;}
int ret;
if(pos<=mid){
ret=insert(lc(now),lc(pre),l,mid,pos);
if(ret) ret=insert(rc(now),rc(pre),mid+1,r,pos);
}else ret=insert(rc(now),rc(pre),mid+1,r,pos);
return pushup(now,l,r),ret;
}
inline int read(){
int x=0;char ch=getchar();
while(!isdigit(ch)) ch=getchar();
while(isdigit(ch)) x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
return x;
}
priority_queue<Heap_node> Q;
int vis[maxn],pre[maxn],root[maxn];
inline int dijkstra(int s,int t){
root[s]=1,Q.push(Heap_node(s,root[s]));
while(!Q.empty()){
Heap_node x=Q.top();Q.pop();
if(vis[u=x.id]) continue;vis[u]=1;
for(int i=Head[u],tmp;i;i=Next[i]){
insert(tmp,root[u],0,mx,W[i]);
if((!root[V[i]])||cmp(tmp,root[V[i]],0,mx)){
root[V[i]]=tmp,pre[V[i]]=u;
Q.push(Heap_node(V[i],root[V[i]]));
}
}
}if(!root[t]) return -1;
return T[root[t]].sum;
}
inline void get(int u){
if(u==s) return void(out[++ans]=u);
return out[++ans]=u,get(pre[u]);
}
int main(){
n=read(),m=read(),P[0]=1;
for(int i=1;i<=m;++i){
u=read(),v=read(),w=read();
add(u,v,w),add(v,u,w),mx=max(mx,w);
}mx+=log2(m)+1,s=read(),t=read();
for(int i=1;i<=mx;++i) P[i]=add(P[i-1],P[i-1]);
printf("%d\n",ans=dijkstra(s,t));
if(ans==-1) return 0;
ans=0,get(t),printf("%d\n",ans);
for(int i=ans;i>=1;--i) printf("%d ",out[i]);
return puts(""),0;
}