zoukankan      html  css  js  c++  java
  • 洛谷 2176 [USACO14FEB]路障Roadblock

    【题意概述】

      修改图中任一一条边的边权,使其加倍,问怎样使修改后图中的1~n的最短路最大。输出最短路的增量。

    【题解】

      先跑一遍dijkstra求出1~n的路径长度,记录下经过的边。枚举这些边进行修改,再跑dijkstra求出某条边修改后的最短路径的长度。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #define LL long long
     5 #define N 200010
     6 #define rg register
     7 using namespace std;
     8 int n,m,tot,ans0,ans1,fa,son,cnt,last[N],pos[N],dis[N],fp[N],fe[N],st[N];
     9 struct edge{int to,pre,d;}e[N];
    10 struct heap{int poi,d;}h[N];
    11 inline int read(){
    12     int k=0,f=1; char c=getchar();
    13     while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar();
    14     while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar();
    15     return k*f;
    16 }
    17 inline void up(int x){
    18     while((fa=(x>>1))>0&&h[fa].d>h[x].d)
    19         swap(h[fa],h[x]),swap(pos[h[fa].poi],pos[h[x].poi]),x=fa;
    20 }
    21 inline void down(int x){
    22     while((son=(x<<1))<=tot){
    23         if(h[son+1].d<h[son].d&&son<tot) son++;
    24         if(h[son].d<h[x].d) swap(h[son],h[x]),swap(pos[h[x].poi],pos[h[son].poi]),x=son;
    25         else break;
    26     }
    27 }
    28 inline void dijkstra(int x){
    29     for(rg int i=1;i<=n;i++) dis[i]=1e9,pos[i]=0;
    30     h[tot=pos[x]=1]=(heap){x,dis[x]=0};
    31     while(tot){
    32         int now=h[1].poi; pos[h[tot].poi]=1; h[1]=h[tot--]; if(tot) down(1);
    33         for(rg int i=last[now],to;i;i=e[i].pre)if(dis[to=e[i].to]>dis[now]+e[i].d){
    34             dis[to]=dis[now]+e[i].d; fp[to]=now; fe[to]=i;
    35             if(!pos[to]) h[pos[to]=++tot]=(heap){to,dis[to]};
    36             else h[pos[to]].d=dis[to];
    37             up(pos[to]);
    38         }
    39     }
    40 } 
    41 int main(){
    42     n=read(); m=read();
    43     for(rg int i=1;i<=m;i++){
    44         int u=read(),v=read(),d=read();
    45         e[++tot]=(edge){v,last[u],d}; last[u]=tot;
    46         e[++tot]=(edge){u,last[v],d}; last[v]=tot;
    47     }
    48     dijkstra(1);
    49     ans0=dis[n];
    50     int now=n;
    51     while(fp[now]){
    52         st[++cnt]=fe[now];
    53 //        printf("now=%d
    ",now);
    54         now=fp[now];
    55     }
    56 //    for(rg int i=1;i<=cnt;i++) printf("%d ",st[i]);
    57     for(rg int i=1;i<=cnt;i++){
    58         int ed=st[i];
    59         if(ed&1) e[ed].d<<=1, e[ed+1].d<<=1;
    60         else e[ed].d<<=1, e[ed-1].d<<=1;
    61         dijkstra(1);
    62         if(ed&1) e[ed].d>>=1, e[ed+1].d>>=1;
    63         else e[ed].d>>=1, e[ed-1].d>>=1;
    64         ans1=max(ans1,dis[n]);
    65 //        printf("dis=%d
    ",dis[n]);
    66     }
    67     printf("%d
    ",ans1-ans0);
    68     return 0;
    69 }
  • 相关阅读:
    STL的二分查找binary_search
    转_HDU_1907&2509 博弈(Nim博弈变形)
    HDU3589_Jacobi symbol_二次剩余
    转载_模运算_归纳得很精华啊
    HDU3501_calculation2_欧拉函数求和
    【转】求小于等于N的与N互质的数的和
    HDU3328_Flipper_纸牌翻转_模拟题
    转_求逆元的两种方法
    HDU2541_Simple Addition Expression
    MySql数据同步(双机热备)已正式应用上平台
  • 原文地址:https://www.cnblogs.com/DriverLao/p/9750171.html
Copyright © 2011-2022 走看看