• BZOJ4289 PA2012Tax(最短路)


      一个暴力的做法是把边看成点,之间的边权为两边的较大权值,最短路即可。但这样显然会被菊花图之类的卡掉。

      考虑优化建图。将边拆成两个有向边,同样化边为点。原图中同一条边在新图中的两个点之间连边权为原边权的边。对于原图同一点的出边按权值从小到大排序,权值相邻的由小到大连边权为差值的边,由大到小连边权为0的边。这样就完成了取max的操作。加上超源超汇即可。

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    using namespace std;
    int read()
    {
        int x=0,f=1;char c=getchar();
        while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
        while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
        return x*f;
    }
    #define N 100010
    #define M 200010
    int n,m,p[M<<1],t=0;
    long long d[M<<1];
    bool flag[M<<1];
    struct data{int to,nxt,len;
    }edge[M<<3];
    struct data3{int x,y,z,i;
    }e[M<<1];
    struct data2
    {
        int x;long long d;
        bool operator <(const data2&a) const
        {
            return d>a.d;
        }
    };
    priority_queue<data2> q;
    void addedge(int x,int y,int z){t++;edge[t].to=y,edge[t].nxt=p[x],edge[t].len=z,p[x]=t;}
    void dijkstra()
    {
        while (!q.empty()) q.pop();
        memset(d,42,sizeof(d));d[0]=0;q.push((data2){0,0});
        memset(flag,0,sizeof(flag));
        for (int i=1;i<=m*2+1;i++)
        {
            while (!q.empty()&&flag[q.top().x]) q.pop();
            if (q.empty()) break;
            data2 v=q.top();q.pop();
            flag[v.x]=1;
            for (int j=p[v.x];j;j=edge[j].nxt)
            if (v.d+edge[j].len<d[edge[j].to])
            {
                d[edge[j].to]=v.d+edge[j].len;
                q.push((data2){edge[j].to,d[edge[j].to]});
            }
        }
    }
    bool cmp1(const data3&a,const data3&b)
    {
        return a.x<b.x;
    }
    bool cmp2(const data3&a,const data3&b)
    {
        return a.z<b.z;
    }
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("bzoj4289.in","r",stdin);
        freopen("bzoj4289.out","w",stdout);
        const char LL[]="%I64d
    ";
    #else
        const char LL[]="%lld
    ";
    #endif
        n=read(),m=read();
        for (int i=1;i<=m;i++)
        e[i].x=e[i+m].y=read(),e[i].y=e[i+m].x=read(),e[i].z=e[i+m].z=read(),e[i].i=i,e[i+m].i=i+m,addedge(i,i+m,e[i].z),addedge(i+m,i,e[i].z);
        sort(e+1,e+m*2+1,cmp1);
        for (int i=1;i<=m*2;i++)
        {
            int t=i;
            while (t<m*2&&e[t+1].x==e[i].x) t++;
            sort(e+i,e+t+1,cmp2);
            for (int j=i;j<t;j++) addedge(e[j].i,e[j+1].i,e[j+1].z-e[j].z);
            for (int j=t;j>i;j--) addedge(e[j].i,e[j-1].i,0);
            i=t;
        }
        for (int i=1;i<=m*2;i++)
        {
            if (e[i].x==1) addedge(0,e[i].i,e[i].z);
            if (e[i].y==n) addedge(e[i].i,m*2+1,e[i].z);
        }
        dijkstra();
        cout<<d[m*2+1];
        return 0;
    }
  • 相关阅读:
    树的直径 poj 2631
    hdu 3954 Level up(线段树)
    [Java Web]Struts2解决中文乱码问题
    怎样为virtualbox添加新的分辨率
    本人的cocos2d-x之路
    php 中利用json_encode和json_decode传递包括特殊字符的数据
    【设计模式】—— 创建者模式Builder
    【设计模式】——工厂方法FactoryMethod
    【Apache开源软件基金会项目】
    【设计模式】——抽象工厂Abstract Factory
  • 原文地址:https://www.cnblogs.com/Gloid/p/9839201.html
Copyright © 2020-2023  润新知