首先,並不必定走「除了上一次來的邊」之外的最短路,但考慮「除了上一次來的邊」之外的最短路和次短路(這裏的次短路指最後一條邊與最短路不一樣的「最短路」),必然是走這二者之一c++
(」除了上一次來的邊「指第一步不走上一次來的邊)ide
證實很顯然,由於若是最短路很差必然是由於下一次須要先走最短路那條邊,那麼此次走次短路便可spa
但因爲咱們所預處理的並不能與實際的$X_{i}$有關(會有修改),但能夠發現對於不少「上一次來的邊」,其最短路和次短路都是同樣的it
具體來講,對於兩點,求出:io
1.最短路(任意一條,如下省略)class
2.與最短路最後一條邊不一樣的「最短路」date
3.與最短路最後一條邊不一樣且與第2條路徑第一條邊不一樣的「最短路」queue
4.與最短路第一條邊的不一樣的「最短路」im
5.與最短路第一條邊不一樣且與第4條路徑最後一條邊不一樣的「最短路」查詢
(前兩個是用來查詢除去的邊沒有用的狀況,而後除去的邊與次短路相同時修改次短路爲第3條,除去的邊與最短路相同時採用第4和第5條)
最短路的記錄用第一條邊、最後一條邊的編號以及長度來描述最短路便可
事實上,這些均可以用$f_{i,j}$表示由第一次通過第$i$條邊、最後一次通過第$j$條邊(無向邊拆爲兩條有向邊來作)的最短路長度來處理,即枚舉兩點以及兩邊(總共$o(m^{2})$)
(有一個細節,就是要特殊處理存在直接路徑的點對)
關於如何求$f_{i,j}$只須要把邊看成點去求dijkstra便可,具體來講就是將原來的標記點改成標記邊便可,但這樣每個邊都作一次最壞會變爲$o(m^{2})$,考慮到最短邊僅僅只是本身的反向邊沒有更新,只須要用第二次搜到的邊更新最短邊的反向邊便可
接下來用$dp_{i,j}$表示走到$X_{i}$且上一次選擇的是第$j$種路徑,根據上述信息不難轉移
修改用線段樹來維護這個dp,即對每個區間維護一個5*5的矩陣表示$X_{l}$到$X_{l+1}$和$X_{r-1}$到$X_{r}$分別使用了什麼路徑,合併枚舉$X_{mid}$到$X_{mid+1}$的路徑便可
時間複雜度爲$o(m^{2}\log_{2}m+5^{3}T\log_{2}L)$,能夠經過
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 2005 4 #define M 4005 5 #define ll long long 6 #define oo (1LL<<60) 7 #define T 100005 8 #define L (k<<1) 9 #define R (L+1) 10 #define mid (l+r>>1) 11 struct ji{ 12 int nex,to,len; 13 }edge[M]; 14 struct path{ 15 int x,y; 16 ll d; 17 bool operator < (const path &k)const{ 18 return d<k.d; 19 } 20 }f[5][N][N]; 21 struct mat{ 22 int l,r,len; 23 ll a[5][5]; 24 path fl[5],fr[5]; 25 }o,tr[T<<2]; 26 priority_queue<pair<ll,int> >q; 27 int E,n,m,t,l,x,y,z,head[N],vis[M],visV[N]; 28 ll ans,d[M],dis[M][M]; 29 void add(int x,int y,int z){ 30 edge[E].nex=head[x]; 31 edge[E].to=y; 32 edge[E].len=z; 33 head[x]=E++; 34 } 35 void dij(int k){ 36 memset(d,0x3f,sizeof(d)); 37 memset(vis,0,sizeof(vis)); 38 memset(visV,-1,sizeof(visV)); 39 d[k]=edge[k].len; 40 q.push(make_pair(-d[k],k)); 41 while (!q.empty()){ 42 k=q.top().second; 43 q.pop(); 44 if (vis[k])continue; 45 vis[k]=1; 46 x=edge[k].to; 47 if (visV[x]<0){ 48 visV[x]=(k^1); 49 for(int i=head[x];i!=-1;i=edge[i].nex) 50 if (((k^i)!=1)&&(d[i]>d[k]+edge[i].len)){ 51 d[i]=d[k]+edge[i].len; 52 q.push(make_pair(-d[i],i)); 53 } 54 } 55 else{ 56 y=visV[x]; 57 if (d[y]>d[k]+edge[y].len){ 58 d[y]=d[k]+edge[y].len; 59 q.push(make_pair(-d[y],y)); 60 } 61 } 62 } 63 } 64 mat merge(mat x,mat y){ 65 if (!x.len)return y; 66 if (!y.len)return x; 67 o.l=x.l,o.r=y.r,o.len=x.len+y.len; 68 memcpy(o.fl,x.fl,sizeof(o.fl)); 69 memcpy(o.fr,y.fr,sizeof(o.fr)); 70 memset(o.a,0x3f,sizeof(o.a)); 71 if (x.len==1){ 72 for(int i=0;i<5;i++){ 73 o.fl[i]=f[i][x.l][y.l]; 74 o.a[i][i]=f[i][x.r][y.l].d; 75 } 76 } 77 else{ 78 for(int i=0;i<5;i++) 79 for(int j=0;j<5;j++) 80 for(int k=0;k<5;k++) 81 if ((x.fr[j].y^f[k][x.r][y.l].x)!=1) 82 o.a[i][k]=min(o.a[i][k],x.a[i][j]+f[k][x.r][y.l].d); 83 } 84 memcpy(x.a,o.a,sizeof(o.a)); 85 memset(o.a,0x3f,sizeof(o.a)); 86 if (y.len==1){ 87 for(int i=0;i<5;i++){ 88 o.fr[i]=f[i][x.r][y.r]; 89 o.a[i][i]=0; 90 } 91 } 92 else{ 93 for(int i=0;i<5;i++) 94 for(int j=0;j<5;j++) 95 for(int k=0;k<5;k++) 96 if ((f[i][x.r][y.l].y^y.fl[j].x)!=1) 97 o.a[i][k]=min(o.a[i][k],y.a[j][k]); 98 } 99 memcpy(y.a,o.a,sizeof(o.a)); 100 memset(o.a,0x3f,sizeof(o.a)); 101 for(int i=0;i<5;i++) 102 for(int j=0;j<5;j++) 103 for(int k=0;k<5;k++)o.a[i][k]=min(o.a[i][k],x.a[i][j]+y.a[j][k]); 104 return o; 105 } 106 void update(int k,int l,int r,int x,int y){ 107 if (l==r){ 108 tr[k].l=tr[k].r=y; 109 tr[k].len=1; 110 return; 111 } 112 if (x<=mid)update(L,l,mid,x,y); 113 else update(R,mid+1,r,x,y); 114 tr[k]=merge(tr[L],tr[R]); 115 } 116 int main(){ 117 scanf("%d%d%d%d",&n,&m,&t,&l); 118 memset(head,-1,sizeof(head)); 119 for(int i=1;i<=m;i++){ 120 scanf("%d%d%d",&x,&y,&z); 121 add(x,y,z); 122 add(y,x,z); 123 } 124 for(int i=1;i<=n;i++) 125 for(int j=1;j<=n;j++) 126 for(int k=0;k<5;k++) 127 if (i==j)f[k][i][j]=path{-1,-1,0}; 128 else f[k][i][j]=path{-1,-1,oo}; 129 for(int i=0;i<E;i++){ 130 dij(i); 131 for(int j=0;j<E;j++)dis[i][j]=d[j]; 132 } 133 for(int i=1;i<=n;i++) 134 for(int j=1;j<=n;j++){ 135 for(int x=head[i];x!=-1;x=edge[x].nex){ 136 if (edge[x].to==j)f[0][i][j]=min(f[0][i][j],path{x,x,edge[x].len}); 137 for(int y=head[j];y!=-1;y=edge[y].nex) 138 f[0][i][j]=min(f[0][i][j],path{x,y^1,dis[x][y^1]}); 139 } 140 for(int x=head[i];x!=-1;x=edge[x].nex){ 141 if ((edge[x].to==j)&&(x!=f[0][i][j].y))f[1][i][j]=min(f[1][i][j],path{x,x,edge[x].len}); 142 for(int y=head[j];y!=-1;y=edge[y].nex) 143 if ((y^f[0][i][j].y)!=1)f[1][i][j]=min(f[1][i][j],path{x,y^1,dis[x][y^1]}); 144 } 145 for(int x=head[i];x!=-1;x=edge[x].nex){ 146 if ((edge[x].to==j)&&(x!=f[0][i][j].y)&&(x!=f[1][i][j].x))f[2][i][j]=min(f[2][i][j],path{x,x,edge[x].len}); 147 for(int y=head[j];y!=-1;y=edge[y].nex) 148 if (((y^f[0][i][j].y)!=1)&&(x!=f[1][i][j].x))f[2][i][j]=min(f[2][i][j],path{x,y^1,dis[x][y^1]}); 149 } 150 f[3][j][i]=path{f[1][i][j].y^1,f[1][i][j].x^1,f[1][i][j].d}; 151 f[4][j][i]=path{f[2][i][j].y^1,f[2][i][j].x^1,f[2][i][j].d}; 152 } 153 for(int i=1;i<=l;i++){ 154 scanf("%d",&x); 155 update(1,1,l,i,x); 156 } 157 for(int i=1;i<=t;i++){ 158 scanf("%d%d",&x,&y); 159 update(1,1,l,x,y); 160 ans=oo; 161 for(int j=0;j<5;j++) 162 for(int k=0;k<5;k++)ans=min(ans,tr[1].a[j][k]); 163 if (ans>=oo)ans=-1; 164 printf("%lld\n",ans); 165 } 166 }