#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <algorithm>
#include <ctime>
#include <functional>
#pragma comment(linker,"/STACK:102400000,102400000")
using namespace std;
#define eps 1e-10
#define N 102000
#define B 1000007
#define M 3000020
#define inf 0x3f3f3f3f
#define LL long long
#define pii pair<int, int>
#define MP make_pair
#define fi first
#define se second
#define md (ll + rr >> 1)
#define ls (i << 1)
#define rs (ls | 1)
#define md (ll + rr >> 1)
#define lson ll, md, ls
#define rson md + 1, rr, rs
const int m1 = 1000000007;
const int m2 = 1000000002;
const int b = 2;
int ch[N * 200][2], cnt[N * 200];
LL hx[N * 200];
int tot;
int p1[N], p2[N];
int fst[N], nxt[M], vv[M], cost[M], e;
int n, m;
int s, t;
int pre[N], rt[N];
bool inq[N];
int ans;
void init() {
memset(fst, -1, sizeof fst);
e = 0;
p1[0] = p2[0] = 1;
for(int i = 1; i < N; ++i) {
p1[i] = 1LL * p1[i - 1] * b % m1;
p2[i] = 1LL * p2[i - 1] * b % m2;
}
}
void add(int u, int v, int c) {
cost[e] = c, vv[e] = v, nxt[e] = fst[u], fst[u] = e++;
}
void push_up(int k, int ll, int rr) {
cnt[k] = cnt[ch[k][0]] + cnt[ch[k][1]];
LL x = hx[ch[k][0]] >> 32;
LL y = hx[ch[k][0]] & ((1LL << 32) - 1);
LL xx = hx[ch[k][1]] >> 32;
LL yy = hx[ch[k][1]] & ((1LL << 32) - 1);
x = (x * p1[rr - md] + xx) % m1;
y = (y * p2[rr - md] + yy) % m2;
hx[k] = (x << 32) + y;
}
int update(int i, int x, int v, int ll, int rr) {
int k = ++tot;
ch[k][0] = ch[i][0];
ch[k][1] = ch[i][1];
cnt[k] = cnt[i] + v;
if(ll == rr) {
hx[k] = ((1LL * v) << 32) + v;
return k;
}
if(x <= md) ch[k][0] = update(ch[i][0], x, v, ll, md);
else ch[k][1] = update(ch[i][1], x, v, md + 1, rr);
push_up(k, ll, rr);
return k;
}
int query(int i, int x, int ll, int rr) {
if(cnt[i] == rr - ll + 1) return -1;
if(ll == rr) {
if(cnt[i] == 1) return -1;
return ll;
}
if(x > md) return query(ch[i][1], x, md + 1, rr);
if(x == ll) {
if(cnt[ch[i][0]] == md - ll + 1) return query(ch[i][1], md + 1, md + 1, rr);
return query(ch[i][0], x, ll, md);
}
int t = query(ch[i][0], x, ll, md);
if(t != -1) return t;
return query(ch[i][1], md + 1, md + 1, rr);
}
int clear0(int i, int l, int r, int ll, int rr) {
if(ll == l && rr == r) {
return 0;
}
int k = ++tot;
ch[k][0] = ch[i][0];
ch[k][1] = ch[i][1];
if(r <= md) ch[k][0] = clear0(ch[i][0], l, r, ll, md);
else if(l > md) ch[k][1] = clear0(ch[i][1], l, r, md + 1, rr);
else {
ch[k][0] = clear0(ch[i][0], l, md, ll, md);
ch[k][1] = clear0(ch[i][1], md + 1, r, md + 1, rr);
}
push_up(k, ll, rr);
return k;
}
bool cmp(int u, int v, int ll, int rr) {
if(hx[u] == hx[v]) return 0;
if(ll == rr) {
return cnt[u] < cnt[v];
}
if(hx[ch[u][1]] != hx[ch[v][1]]) return cmp(ch[u][1], ch[v][1], md + 1, rr);
return cmp(ch[u][0], ch[v][0], ll, md);
}
void dfs(int u, int ll, int rr) {
if(ll == rr) {
if(cnt[u]) ans = ans * 2 + 1;
else ans *= 2;
ans %= m1;
return;
}
dfs(ch[u][1], md + 1, rr);
dfs(ch[u][0], ll, md);
}
struct node {
int x, d;
node() {}
node(int x, int d):x(x), d(d) {}
bool operator < (const node &b) const {
return cmp(b.d, d, 0, N - 1);
}
};
void spfa() {
priority_queue<node> q;
q.push(node(s, rt[s]));
for(int i = 1; i <= n; ++i) if(i != s) rt[i] = update(0, N - 1, 1, 0, N - 1);
while(!q.empty()) {
int u = q.top().x;
int d = q.top().d;
q.pop();
if(rt[u] != d) continue;
for(int i = fst[u]; ~i; i = nxt[i]) {
int v = vv[i], c = cost[i];
int p = query(rt[u], c, 0, N - 1);
if(p == -1) {
vector<int> g1;
g1[1] = -1;
}
int t = rt[u];
if(p > c) t = clear0(t, c, p - 1, 0, N - 1);
t = update(t, p, 1, 0, N - 1);
if(cmp(t, rt[v], 0, N - 1)) {
rt[v] = t;
pre[v] = u;
q.push(node(v, rt[v]));
}
}
}
}
int main() {
scanf("%d%d", &n, &m);
init();
for(int i = 1; i <= m; ++i) {
int u, v, c;
scanf("%d%d%d", &u, &v, &c);
add(u, v, c);
add(v, u, c);
}
scanf("%d%d", &s, &t);
if(s == t) {
printf("0\n1\n1\n");
return 0;
}
spfa();
if(pre[t] == 0) {
puts("-1");
return 0;
}
dfs(rt[t], 0, N - 1);
printf("%d\n", ans);
vector<int> vt; vt.push_back(t);
while(t != s) {
t = pre[t];
vt.push_back(t);
}
reverse(vt.begin(), vt.end());
printf("%d\n", (int)vt.size());
for(int i = 0; i < vt.size(); ++i) {
printf("%d%c", vt[i], i == vt.size() - 1? '\n': ' ');
}
return 0;
}
Codeforces 464E The Classic Problem (线段树+哈希)
最新推荐文章于 2022-08-14 17:13:00 发布