/* https://arxiv.org/abs/1906.04062 の p17 の algorithm の実装をしています。 */ #include using namespace std; #include using namespace atcoder; using ll=long long; const ll inf=1e18; using T=ll; ll op(ll a,ll b){ return a^b; } ll e(){ return 0; } ll inv(ll x){ return x; } // template struct shortest_non_zero_path{ templateusing pqmin=priority_queue,greater>; struct edge{ int to; ll cost; T x; int id; }; int n,m; vector> g; shortest_non_zero_path(){} shortest_non_zero_path(int n):n(n),m(0),g(n){} void add_edge(int u,int v,ll c,T x){ g[u].push_back({v,c,x,m}); g[v].push_back({u,c,inv(x),m}); m++; } vector solve(int s){ // step0: 最短路木の作成 vector dist_T(n,inf); vector depth_T(n,-1); vector pred_T(n,-1); vector label_T(n,e()); pqmin> pq_T; dist_T[s]=0,depth_T[s]=0,label_T[s]=e(); pq_T.push({dist_T[s],s}); while(pq_T.size()){ auto[d,p]=pq_T.top();pq_T.pop(); if(dist_T[p]dist_T[p]+e.cost){ dist_T[e.to]=dist_T[p]+e.cost; depth_T[e.to]=depth_T[p]+1; pred_T[e.to]=p; label_T[e.to]=op(label_T[p],e.x); pq_T.push({dist_T[e.to],e.to}); } } } // step1: q(v), uf の初期化 vector q(n,inf); for(int v=0;v root(n); for(int v=0;v h(m,inf); vector u(m),v(m); pqmin> pq_F; for(int i=0;ie.to)continue; u[e.id]=i,v[e.id]=e.to; if(op(label_T[i],e.x)!=label_T[e.to]){ h[e.id]=dist_T[i]+dist_T[e.to]+e.cost; pq_F.push({h[e.id],e.id}); } } } // step3: h が空になるまで実行する while(pq_F.size()){ // step3.1: pq_F から最小の h(e) なる e を取り、w1,w2 を計算 auto[he,e]=pq_F.top();pq_F.pop(); if(h[e]!=he)continue; int w1=root[ds.leader(u[e])]; int w2=root[ds.leader(v[e])]; // step3.2: B に wi を加え、dsu の更新 set B; while(w1!=w2){ if(depth_T[w1]q[w]+dist_T[f.to]+f.cost){ h[f.id]=q[w]+dist_T[f.to]+f.cost; pq_F.push({h[f.id],f.id}); } } } } // step4 : 結果を返す return q; } }; int main(){ cin.tie(nullptr)->sync_with_stdio(false); int N,M,K;cin>>N>>M>>K; vector A(M),B(M),C(M),X(M); for(int i=0;i>A[i]>>B[i]>>C[i]; A[i]--,B[i]--; string s;cin>>s; for(auto&&e:s)X[i]=2*X[i]+(e-'0'); } shortest_non_zero_path solver(N); for(int i=0;i