cf 843 D Dynamic Shortest Path [最短路+bfs]

题面:

传送门

思路:

真·动态最短路

但是因为每次只加1

所以可以每一次修改操作的时候使用距离分层的bfs,在O(n)的时间内解决修改

这里要用到一个小技巧:

把每条边(u,v)的边权表示为dis[u]+w(u,v)-dis[v],这样边权实际上变成了“这条边离作为最短路的一份子还差了多少”

然后在用这个边权的新图里面更新1到每个点的最短路,再用原来的dis加上这个值,就是当前的最短路了

实际上是把绝对数值转化为了“离最优解的距离”,以此解题

Code:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<queue>
 6 #define ll long long
 7 #define inf 1e15
 8 #define mp make_pair
 9 using namespace std;
10 inline int read(){
11     int re=0,flag=1;char ch=getchar();
12     while(ch>'9'||ch<'0'){
13         if(ch=='-') flag=-1;
14         ch=getchar();
15     }
16     while(ch>='0'&&ch<='9') re=(re<<1)+(re<<3)+ch-'0',ch=getchar();
17     return re*flag;
18 }
19 int n,m,cnt,first[100010];ll dis[100010];
20 struct edge{
21     int to,next,w;
22 }a[100010];
23 inline void add(int u,int v,int w){
24     a[++cnt]=(edge){v,first[u],w};first[u]=cnt;
25 }
26 struct node{
27     int x;node(){x=0;}
28     node(int xx){x=xx;}
29     bool operator <(node r) const {
30         return dis[x]>dis[r.x];
31     }
32 };
33 int delta[100010];
34 priority_queue<node>qq;
35 void spfa(){
36     int i,u,v;
37     for(i=1;i<=n;i++) dis[i]=inf;
38     dis[1]=0;qq.push(node(1));
39     while(!qq.empty()){
40         u=qq.top().x;qq.pop();
41         for(i=first[u];~i;i=a[i].next){
42             v=a[i].to;
43             if(dis[v]>dis[u]+(ll)a[i].w){
44                 dis[v]=dis[u]+(ll)a[i].w;
45                 qq.push(node(v));
46             }
47         }
48     }
49 }
50 queue<int>q[100010];
51 void bfs(){
52     memset(delta,0x3f,sizeof(delta));
53     int i,j,u,v,w,maxn,head=0,tail=1;
54     q[0].push(1);delta[1]=maxn=0;
55     for(i=0;i<=maxn;i++){
56         while(!q[i].empty()){
57             u=q[i].front();q[i].pop();
58             if(i>delta[u]) continue;
59             for(j=first[u];~j;j=a[j].next){
60                 v=a[j].to;w=a[j].w;
61                 if(delta[v]>delta[u]+dis[u]+w-dis[v]){
62                     delta[v]=delta[u]+dis[u]+w-dis[v];
63                     if(delta[v]<=n){
64                         q[delta[v]].push(v);maxn=max(maxn,delta[v]);
65                     }
66                 }
67             }
68         }
69     }
70 }
71 int main(){
72 //    freopen("d.in","r",stdin);
73     memset(first,-1,sizeof(first));
74     int i,j,t1,t2,t3,Q;
75     n=read();m=read();Q=read();
76     for(i=1;i<=m;i++){
77         t1=read();t2=read();t3=read();
78         add(t1,t2,t3);
79     }
80     spfa();
81     for(i=1;i<=Q;i++){
82         t1=read();
83         if(t1==1) t2=read(),printf("%I64d
",(dis[t2]>=inf)?-1:dis[t2]);
84         else{
85             t2=read();
86             memset(delta,0,sizeof(delta));
87             for(j=1;j<=t2;j++) t3=read(),a[t3].w++;
88             bfs();
89             for(j=1;j<=n;j++) dis[j]+=(ll)delta[j];
90 //            cout<<endl;
91         }
92     }
93 //    system("pause");
94     return 0;
95 }
原文地址:https://www.cnblogs.com/dedicatus545/p/8455313.html