Description
Input
Output
Sample Input
6 7
1 2 1
2 3 1
3 4 2
4 5 1
5 6 1
1 3 3
4 6 3
1 6
4
1 2
1 3
4 3
6 5
Sample Output
7
6
Infinity
7
HINT
In fact, this problem and [tjoi2012] bridge basically almost, if not the shortest path on the edge, then the direct output is shortest. Otherwise, you can follow the [tjoi2012] bridge problem.
/*program from wolfycz*/#include <cmath> #include <cstdio> #include <cstring> #include <iostream > #include <algorithm> #include <unordered_set> #define INF 0x7f7f7f7f7f7f7f7fusing namespace std; typedef long Long ll;typedef unsigned int ui;typedef unsigned long long ull;inline int read () {int X=0,f=1;char ch=getc Har (); for (;ch< ' 0 ' | | Ch> ' 9 '; Ch=getchar ()) if (ch== '-') f=-1; for (; ch>= ' 0 ' &&ch<= ' 9 '; Ch=getchar ()) x= (x<<1) + (x<<3) +ch-' 0 '; return x*f;} inline void print (int x) {if (x>=10) print (X/10); Putchar (x%10+ ' 0 ');} const int N=2e5,m=2e5;int pre[(m<<1) +10],now[n+10],child[(m<<1) +10],val[(m<<1) +10];int Fa[N+10], Lca[n+10],stack[n+10],dfn[n+10];bool vis[n+10],flag[(m<<1) +10];int n,m,tot,num,max;ll Dis,Ans[N+10];struct myhash{size_t operator () (const pair<int,int> &x) const{return ((Hash<int> () (X.first) <<1) ^ (hash<int> () (X.second)) >>1; }};unOrdered_set<pair<int,int>,myhash>st;struct s1{#define LS (p<<1) #define RS (p<<1|1) #def Ine fa (p>>1) struct node{int X;ll v; BOOL operator < (const node &a) Const{return v<a.v;} }Q[N+10]; int tot; void Insert (int x,ll v) {q[++tot]= (node) {x,v}; int P=tot; while (P!=1&&Q[P]<Q[FA]) swap (Q[P],Q[FA]), P=FA; } void Delete () {q[1]=q[tot--]; int P=1,son; while (Ls<=tot) {if (rs>tot| | Q[LS]<Q[RS]) Son=ls; else Son=rs; if (Q[son]<q[p]) swap (Q[p],q[son]), P=son; else break; }}}heap;struct segment{ll tree[(n<<2) +10]; Segment () {memset (tree,127,sizeof (tree));} void Add_tag (int p,ll v) {tree[p]=min (tree[p],v);} void pushdown (int p) {if (tree[p]==inf) return; Add_tag (Ls,tree[p]); Add_tag (Rs,tree[p]); } void Modify (int p,int l,int r,int x,int y,lL V) {if (x<=l&&r<=y) {Add_tag (p,v); Return } int mid= (L+R) >>1; if (x<=mid) Modify (LS,L,MID,X,Y,V); if (y>mid) Modify (RS,MID+1,R,X,Y,V); } void traversals (int p,int l,int R) {if (l==r) {ans[l]=tree[p]; Return } pushdown (P); int mid= (L+R) >>1; Traversals (Ls,l,mid); Traversals (RS,MID+1,R); }}tree;struct s2{ll dis[n+10]; S2 () {memset (dis,63,sizeof (DIS));}} Frw,bck;void Join (int x,int y,int z) {pre[++tot]=now[x],now[x]=tot,child[tot]=y,val[tot]=z;} void Insert (int x,int y,int z) {join (x, Y, z), join (Y,X,Z);} void Dijkstra (int x,ll *dis) {memset (vis,0,sizeof (VIS)); Heap.insert (x,dis[x]=0); while (heap.tot) {int now=heap.q[1].x; Heap.delete (); if (Vis[now]) continue; Vis[now]=1; for (int p=now[now],son=child[p];p; p=pre[p],son=child[p]) {if (Dis[son]>dis[now]+val[p]) { DIS[SON]=DIS[NOW]+VAL[P]; Heap.insert (Son,dis[son]); }}}}void Put_flag (int x) {for (int p=now[x],son=child[p];p; p=pre[p],son=child[p]) {if (Frw.dis[x]+va L[p]+bck.dis[son]==dis) {St.insert (Make_pair (X,son)); St.insert (Make_pair (son,x)); flag[p]=flag[p+ (p&1?1:-1)]=1; Put_flag (son); Return }}}void Find_fa (int x) {for (int p=now[x],son=child[p];p; p=pre[p],son=child[p]) if (frw.dis[x]+val[p]==frw.d is[son]&&! Fa[son]) Fa[son]=x,find_fa (son); void Fill (int x,int v) {if (lca[x]) return; Lca[x]=v; for (int p=now[x],son=child[p];p; p=pre[p],son=child[p]) if (fa[son]==x) Fill (son,v);} void Get_lca (int x) {int top=0; while (x) {Fill (x,x); Stack[++top]=x; X=FA[X]; } for (int i=top;i;i--) dfn[stack[i]]=num++; num--;} int main () {int n=read (), M=read (); for (int i=1;i<=m;i++) {int x=read (), Y=read (),Z=read (); Insert (x, y, z); } int S=read (), T=read (); Dijkstra (S,frw.dis); Dijkstra (T,bck.dis); DIS=FRW.DIS[T]; Put_flag (S); FIND_FA (S); Get_lca (T); for (int i=1;i<=tot;i+=2) {if (flag[i]) continue; int x=child[i],y=child[i+1],v=val[i]; if (Lca[x]==lca[y]) continue; if (Dfn[lca[x]]>dfn[lca[y]]) swap (x, y); ll Tmp=frw.dis[x]+v+bck.dis[y]; Tree.modify (1,1,NUM,DFN[LCA[X]]+1,DFN[LCA[Y]],TMP); } tree.traversals (1,1,num); int Q=read (); for (int i=1;i<=q;i++) {int x=read (), Y=read (); if (!st.count (Make_pair (x, y))) {printf ("%lld\n", Dis); Continue } printf (Ans[max (dfn[x],dfn[y])]==inf? " Infinity\n ":"%lld\n ", Ans[max (Dfn[x],dfn[y])); } return 0;}
[Violet 6] dream of hometown