• 2018.12.30-dtoj-2659-Tax


    题目描述:

    给出一个N个点M条边的无向图,经过一个点的代价是进入和离开这个点的两条边的边权的较大值,求从起点1到点N的最小代价。起点的代价是离开起点的边的边权,终点的代价是进入终点的边的边权
    N<=100000
    M<=200000

    算法标签:dijk,建边优化

    思路:

    考虑重新建图,容易想到把两条边合成一条边,边权是两边之间的最大值,这样边的条数是m跑不过,考虑优化建边。对于每个顶点,我们仅把这个点的入边与和我大小相同的出边相连,因为我们把双向边拆成单向边,所以必然存在与自己的大小相等的出边。再把每条出边像比自己小的边连0,比自己大的边连权值的差值,这么建边条数是m级别的。

    以下代码:

    #include<bits/stdc++.h>
    #define il inline
    #define LL long long
    #define _(d) while(d(isdigit(ch=getchar())))
    using namespace std;
    const int N=4e5+5,M=4e6+5;
    struct node{int x,v;};vector<node> v[N];
    int n,m,s,t,head[N],ne[M],to[M],w[M],cnt;LL d[N];
    struct data{int x;LL d;bool operator<(const data&t1)const{return d>t1.d;};};
    bool cmp(node t1,node t2){return t1.v<t2.v;}priority_queue<data> q;
    il int read(){int x;char ch;_(!);x=ch^48;_()x=(x<<1)+(x<<3)+(ch^48);return x;}
    il void insert(int x,int y,int z){ne[++cnt]=head[x];head[x]=cnt;to[cnt]=y;w[cnt]=z;}
    il void dijk(){
        for(int i=1;i<=t;i++)d[i]=1e18;q.push((data){s,0});
        while(!q.empty()){
            data now=q.top();q.pop();int x=now.x;if(now.d!=d[x])continue;
            for(int i=head[x];i;i=ne[i])
                if(d[to[i]]>d[x]+w[i])d[to[i]]=d[x]+w[i],q.push((data){to[i],d[to[i]]});
        }
    }
    int main()
    {
        n=read();m=read();s=0;t=2*m+1;
        for(int i=1;i<=m;i++){
            int x=read(),y=read(),z=read();
            v[x].push_back((node){i,z});
            v[y].push_back((node){i+m,z});
            insert(i,i+m,z);insert(i+m,i,z);
        }
        for(int i=0;i<v[1].size();i++)insert(s,v[1][i].x,v[1][i].v);
        for(int i=0;i<v[n].size();i++)insert(v[n][i].x,t,0);
        for(int i=2;i<n;i++){
            sort(v[i].begin(),v[i].end(),cmp);
            for(int j=1;j<v[i].size();j++){
                insert(v[i][j-1].x,v[i][j].x,v[i][j].v-v[i][j-1].v);
                insert(v[i][j].x,v[i][j-1].x,0);
            }
        }
        dijk();printf("%lld
    ",d[t]);
        return 0;
    }
    View Code
     
     
  • 相关阅读:
    Java实现二分图的最大权匹配
    Java实现二分图的最大权匹配
    Java实现二分图的最大权匹配
    Java实现二分图的最大权匹配
    Java实现二分图的最大权匹配
    Qt技术优势
    关于qtcreator+vs2008+CDB调试太卡的问题研究(载入符号表,以及VS调试器的注册表信息)
    用友的BS专用浏览器方案
    专访Rust——由Mozilla开发的系统编程语言(目标人群就是那些纠结的C++程序员,甚至也是他们自己)
    比较DirectX和OpenGL的区别(比较详细)
  • 原文地址:https://www.cnblogs.com/Jessie-/p/10199172.html
Copyright © 2020-2023  润新知