zoukankan      html  css  js  c++  java
  • P4366 [Code+#4]最短路 建图 最短路

    P4366 [Code+#4]最短路

    题目链接

    ​ 建图,最短路。

    (n ^ 2 + m)条边肯定是不允许的。那(m)条边肯定是要建的,考虑(n ^ 2)那些边怎么建比较好。

    ​ 我们发现有一些边是没有用的,举个例子。

    如果我们要从1走到4
    1 ^ 4 = 5, 总路程为5c
    1 ^ 0 = 1, 0 ^ 4 = 4, 总路程为5c
    

    ​ 也就是说,有一些边可以被另一些边代替,那么具体一点就是:

    ​ 只需要对(i, i + 2 ^ 0, i + 2 ^ 1, i + 2 ^ 2……)这些点连边就好了。

    ​ 那么现在就只有(nlongn +m)条边了,然后就可以愉快的dij了。

    #include <bits/stdc++.h>
    
    using namespace std;
    
    inline long long read() {
        long long s = 0, f = 1; char ch;
        while(!isdigit(ch = getchar())) (ch == '-') && (f = -f);
        for(s = ch ^ 48;isdigit(ch = getchar()); s = (s << 1) + (s << 3) + (ch ^ 48));
        return s * f;
    }
    
    const int N = 1e5 + 5, M = 5e6 + 5;
    const long long inf = 1e18;
    int n, m, c, s, t, cnt;
    int vis[N], head[N];
    long long dis[N];
    struct edge { int to, nxt, val; } e[M];
    
    void add(int x, int y, int z) {
        e[++ cnt].nxt = head[x]; head[x] = cnt; e[cnt].to = y; e[cnt].val = z;
    }
    
    void run_dij() {
        priority_queue <pair<long long, int>, vector<pair<long long, int> >, greater<pair<long long, int> > > q;
        for(int i = 0;i <= n; i++) dis[i] = inf; 
        dis[s] = 0; q.push(make_pair(dis[s], s));
        while(!q.empty()) {
            int x = q.top().second; q.pop();
            if(vis[x]) continue; vis[x] = 1;
            if(x == t) break; //一个优化,不然会T几个点
            for(int i = head[x]; i ; i = e[i].nxt) {
                int y = e[i].to; 
                if(dis[y] > dis[x] + e[i].val) 
                    dis[y] = dis[x] + e[i].val, q.push(make_pair(dis[y], y));
            }
        }
    }
    
    int main() {
    
        n = read(); m = read(); c = read();
        for(int i = 1, x, y, z;i <= m; i++) x = read(), y = read(), z = read(), add(x, y, z);
        for(int i = 0;i <= n; i++) //注意0也要加边
            for(int j = 0;(1 << j) <= n; j++) {
                if((i ^ (1 << j)) > n) continue;
                int tmp = i ^ (1 << j); add(i, tmp, (1 << j) * c);
            } 
        s = read(); t = read();
        run_dij(); printf("%lld", dis[t]);
    
        return 0;
    }
    
  • 相关阅读:
    Java搭建邮件服务器并发送Excel附件
    Java发送Http带HEADER参数
    MySql 技术内幕 (查询处理和子查询)
    《MySQL技术内幕:SQL编程》笔记
    MySql 技术内幕 (数据类型)
    替换Jar包里文件
    [Python数据分析]新股破板买入,赚钱几率如何?
    一些资料
    sqlval
    IBM CLI 和 ODBC
  • 原文地址:https://www.cnblogs.com/czhui666/p/13789169.html
Copyright © 2011-2022 走看看