zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    Sass 初级学习三
    Sass 初级学习二
    Sass 初级学习一
    数据库0,1和flase true的转换
    Mybatis逆向工程-mybatis generator
    码畜生活现状
    【抽五分钟】使用VuePress创建在线文档中心
    面经整理
    C#引用fo-dicom读取dicom文件异常
    windows10更新后, VMWare无法启动虚拟机: vmdb-14 pipe connection has been broken
  • 原文地址:https://www.cnblogs.com/dedicatus545/p/8455313.html
Copyright © 2011-2022 走看看