[loj2842]野豬

首先,並不必定走「除了上一次來的邊」之外的最短路,但考慮「除了上一次來的邊」之外的最短路和次短路(這裏的次短路指最後一條邊與最短路不一樣的「最短路」),必然是走這二者之一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)$,能夠經過

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk= watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=
  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 } 
View Code
相關文章
相關標籤/搜索