• [hdu5521 Meeting]最短路


    题意:有N个点,给定M个集合,集合Si里面的点两两之间的距离都为Ti,集合里面的所有点数之和<=1e6。有两个人分别在1和N处,求1个点使得两个人到这一点距离的最大值最小

    思路:这题是裸的最短路问题,难点在建图。然而建图也只有1步,在集合外新建1个点,每个点向它连一条Ti/2的边(避免浮点数,可以先乘2,然后结果除以2)。如此巧妙。。。

    #include <bits/stdc++.h>
    using namespace std;
    #define X first
    #define Y second
    #define pb(x) push_back(x)
    #define mp(x, y) make_pair(x, y)
    #define all(a) (a).begin(), (a).end()
    #define mset(a, x) memset(a, x, sizeof(a))
    #define mcpy(a, b) memcpy(a, b, sizeof(b))
    #define cas() int T, cas = 0; cin >> T; while (T --)
    template<typename T>bool umax(T&a, const T&b){return a<b?(a=b,true):false;}
    template<typename T>bool umin(T&a, const T&b){return b<a?(a=b,true):false;}
    typedef long long ll;
    typedef pair<int, int> pii;
    
    #ifndef ONLINE_JUDGE
        #include "local.h"
    #endif
    
    const int N = 1e6 + 7;
    
    struct Edge {
        int u, v, w;
        int next;
        Edge(int u, int v, int w) {
            this->u = u;
            this->v = v;
            this->w = w;
        }
        Edge() {}
    };
    int SZ;
    int head[N];
    Edge edge[N << 1];
    ll d1[N], dn[N];
    int n, m, nn;
    bool used[N];
    
    void add(int u, int v, int w) {
        edge[SZ] = Edge(u, v, w);
        edge[SZ].next = head[u];
        head[u] = SZ ++;
    }
    
    void spfa(int s, ll d[]) {
        queue<int> Q;
        for (int i = 1; i <= nn; i ++) d[i] = pow(10, 18) + 7;
        d[s] = 0;
        mset(used, 0);
        Q.push(s);
        while (!Q.empty()) {
            int u = Q.front(); Q.pop();
            used[u] = false;
            for (int i = head[u]; ~i; i = edge[i].next) {
                Edge e = edge[i];
                if (umin(d[e.v], d[u] + e.w)) {
                    if (!used[e.v]) {
                        Q.push(e.v);
                        used[e.v] = true;
                    }
                }
            }
        }
    }
    
    int main() {
    #ifndef ONLINE_JUDGE
        freopen("in.txt", "r", stdin);
        //freopen("out.txt", "w", stdout);
    #endif // ONLINE_JUDGE
        int t, s, u;
        cas() {
            printf("Case #%d: ", ++ cas);
            cin >> n >> m;
            nn = n;
            mset(head, -1);
            SZ = 0;
            for (int i = 0; i < m; i ++) {
                scanf("%d%d", &t, &s);
                nn ++;
                for (int j = 0; j < s; j ++) {
                    scanf("%d", &u);
                    add(u, nn, t);
                    add(nn, u, t);
                }
            }
            spfa(1, d1);
            spfa(n, dn);
            ll mind = pow(10, 18);
            bool yes = false;
            vector<int> ans;
            for (int i = 1; i <= n; i ++) {
                if (umin(mind, max(d1[i], dn[i]))) yes = true;
            }
            if (!yes) {
                puts("Evil John");
                continue;
            }
            cout << mind / 2 << endl;
            for (int i = 1; i <= n; i ++) {
                if (max(d1[i], dn[i]) == mind) {
                    ans.pb(i);
                }
            }
            sort(all(ans));
            for (int i = 0; i < ans.size(); i ++) {
                printf("%d%c", ans[i], i == ans.size() - 1? '
    ' : ' ');
            }
        }
        return 0;
    }
    

      

  • 相关阅读:
    通信接收机同步模块
    CAZAC序列
    Verilog Tricks
    载波同步
    Matlab step方法
    CRC校验码
    比特冗余
    Vivado RAM使用
    collection
    hashlib
  • 原文地址:https://www.cnblogs.com/jklongint/p/4926268.html
Copyright © 2020-2023  润新知