• bzoj 4398:福慧双修


    学习了一下最短路的姿势,这个建图方法好妙啊,虽然不会证明正确性……

    #include <bits/stdc++.h>
    #define N 220000
    #define INF 1000000000
    using namespace std;
    int n, m;
    int ai[N], bi[N], ci[N], di[N];
    int check;
    class DIJ
    {
    private:
        struct node {int t, d;};
        struct comp {int operator () (node a, node b) {return a.d > b.d;}};
        priority_queue <node, vector <node>, comp> Q;
    public:
        vector <int> bi[N], ci[N];
        int dis[N], vis[N], pre[N];
        int tot;
        void build(int a, int b, int c)
        {
            bi[a].push_back(b); ci[a].push_back(c);
            //if (check) printf("%d %d %d
    ",a,b,c);  
        }
        void solve()
        {
            for (int i = 2; i <= tot; ++ i) dis[i] = INF, vis[i] = 0;
            dis[1] = vis[1] = 0;
            Q.push((node){1, 0});
            while (!Q.empty())
            {
                int hd;
                do hd = Q.top().t, Q.pop();
                while (vis[hd] && !Q.empty());
                if (vis[hd]) break; else vis[hd] = 1;
                for (int j = 0; j < bi[hd].size(); ++ j)
                    if (dis[hd] + ci[hd][j] < dis[bi[hd][j]])
                    {
                        dis[bi[hd][j]] = dis[hd] + ci[hd][j];
                        pre[bi[hd][j]] = hd == 1? bi[hd][j]: pre[hd];
                        Q.push((node){bi[hd][j], dis[bi[hd][j]]});
                    }
            }
        }
    } A, B;
    int tot, ans = INF, bac = INF, pp;
    int main()
    {
        scanf("%d%d", &n, &m); A.tot = n; B.tot = n + 1;
        for (int i = 1; i <= m; ++ i) 
        {
            int a, b, c, d;
            scanf("%d%d%d%d", &a, &b, &c, &d);
            tot ++; ai[tot] = a; bi[tot] = b; ci[tot] = c;
            tot ++; ai[tot] = b; bi[tot] = a; ci[tot] = d;
            A.build(a, b, c);
            A.build(b, a, d);
            if (a == 1 || b == 1) if (bac > c + d) bac = c + d, pp = (a == 1? b: a);
        }
        A.solve();
        A.dis[1] = bac; A.pre[1] = pp;
        check = 1;
        for (int i = 1; i <= tot; ++ i)
        {
            if (ai[i] == 1)
            {
                if (A.pre[bi[i]] != bi[i])
                    B.build(1, bi[i], ci[i]);
            }
            else if (bi[i] == 1)
            {
                if (A.pre[ai[i]] != ai[i])
                    B.build(1, n + 1, A.dis[ai[i]] + ci[i]);
                else B.build(ai[i], n + 1, ci[i]);
            }
            else if (A.pre[ai[i]] != A.pre[bi[i]])
                B.build(1, bi[i], A.dis[ai[i]] + ci[i]);
            else B.build(ai[i], bi[i], ci[i]);
        }
        B.solve();
        printf("%d
    ", B.dis[n + 1]);
    }
  • 相关阅读:
    pycurl之公共方法--请求/上传/下载,解析json
    BAT启动关闭VMWARE的虚拟机
    LINUX免密登录SSH下的操作之自动COPY部署到其他机器
    python 可迭代对象
    python itertools 迭代器增加元素
    python django
    《Linux下mysql安装》
    linux下安装mysql
    hive基本语法
    linux连接工具MobaXterm下载及使用
  • 原文地址:https://www.cnblogs.com/AwD-/p/6257803.html
Copyright © 2020-2023  润新知