zoukankan      html  css  js  c++  java
  • BZOJ 3445: [Usaco2014 Feb] Roadblock

    Description

    一个图, (n) 个点 (m) 条边,求将一条边距离翻倍后使 (1-n) 最短路径增加的最大增量.

    Sol

    Dijstra.

    先跑一边最短路,然后枚举最短路,将路径翻倍然后跑Dijstra...

    因为不在最短路径上的边没用贡献,然后最短路径最长为 (n-1)

    复杂度 (O(nmlogm)

    Code

    /**************************************************************
        Problem: 3445
        User: BeiYu
        Language: C++
        Result: Accepted
        Time:32 ms
        Memory:3332 kb
    ****************************************************************/
     
    #include <cstdio>
    #include <cstring>
    #include <utility>
    #include <vector>
    #include <queue>
    #include <functional>
    #include <iostream>
    using namespace std;
     
    typedef long long LL;
    typedef pair< LL,int > pr;
    #define mpr make_pair
    const int N = 255;
     
    int n,m,cnt;
    int b[N],p[N];
    LL ans,disn;
    LL d[N];
    struct Edge{ int fr,to;LL w; }edge[N*N*2];
    vector< int > g[N];
    priority_queue< pr,vector< pr >,greater< pr > > q;
    vector< int > path;
     
    inline int in(int x=0){ scanf("%d",&x);return x; }
    void Add_Edge(int fr,int to,int w){
        edge[++cnt]=(Edge){ fr,to,w };
        g[fr].push_back(cnt);
    }
    void GetPath(){
        for(int x=n;x!=1;x=edge[p[x]].fr) path.push_back(p[x]);
    }
    void Dijstra(int s,int fst){
        memset(b,0,sizeof(b));
        memset(d,0x3f,sizeof(d));
        d[s]=0,q.push(mpr(0LL,s));
        for(int x;!q.empty();){
            x=q.top().second,q.pop();if(b[x]) continue;b[x]=1;
            for(int i=0,lim=g[x].size();i<lim;i++){
                int v=edge[g[x][i]].to;LL w=edge[g[x][i]].w;
    //          cout<<x<<" "<<v<<" "<<w<<" "<<d[x]<<" "<<d[v]<<endl;
                if(d[x]+w < d[v]){
                    d[v]=d[x]+w,p[v]=g[x][i];
                    q.push(mpr(d[v],v));
                }
            }
        }
    //  cout<<d[n]<<endl;
        if(fst) disn=d[n],GetPath();
        else ans=max(ans,d[n]-disn);
    }
    int main(){
        n=in(),m=in();
        for(int i=1,u,v,w;i<=m;i++) u=in(),v=in(),w=in(),Add_Edge(u,v,w),Add_Edge(v,u,w);
        Dijstra(1,1);
         
    //  for(int i=0,lim=path.size();i<lim;i++) cout<<edge[path[i]].fr<<" "<<edge[path[i]].to<<" "<<edge[path[i]].w<<endl;
         
        for(int i=0,lim=path.size();i<lim;i++) edge[path[i]].w*=2,Dijstra(1,0),edge[path[i]].w/=2;
        cout<<ans<<endl;
        return 0;
    }
    

      

  • 相关阅读:
    2015年个人记录
    Win10如何新建用户怎么添加新账户
    快速搭建一个本地的FTP服务器
    天气接口
    一张图搞定OAuth2.0
    PHP TS 和 NTS 版本选择
    如何在 Laravel 中使用 SMTP 发送邮件(适用于 163、QQ、Gmail 等)
    Npm vs Yarn 之备忘详单
    浅谈CSRF
    值得看的cookie详解
  • 原文地址:https://www.cnblogs.com/beiyuoi/p/6071604.html
Copyright © 2011-2022 走看看