[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? ‘\n‘ : ‘ ‘);
        }
    }
    return 0;
}

  

时间: 2024-10-22 08:22:47

[hdu5521 Meeting]最短路的相关文章

hdu-5521 Meeting(最短路)

题目链接: Meeting Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 2024    Accepted Submission(s): 628 Problem Description Bessie and her friend Elsie decide to have a meeting. However, after Farm

HDU 5521.Meeting 最短路模板题

Meeting Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 3361    Accepted Submission(s): 1073 Problem Description Bessie and her friend Elsie decide to have a meeting. However, after Farmer Jo

2015沈阳区域赛Meeting(最短路 + 建图)

Meeting Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 6865    Accepted Submission(s): 2085 Problem Description Bessie and her friend Elsie decide to have a meeting. However, after Farmer Jo

HDU 5521 Meeting(虚拟节点+最短路)

Meeting Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Total Submission(s): 1358    Accepted Submission(s): 435 Problem Description Bessie and her friend Elsie decide to have a meeting. However, after Farmer Jo

Hdu 5521 Meeting(建图+最短路)

题目地址:http://acm.split.hdu.edu.cn/showproblem.php?pid=5521 思路:边数太多,不能直接建图.对于每个集合,设置一个虚拟点,对于每个集合中的点u:连一条u->S权值为0的边(点在集合中,花费为0):连一条S->u权值为w的边(从集合中一点到另一点花费w).分别计算从点1到i和从点n到i的最短路,枚举i,则ans=min( ans,max ( dist[0][i],dist[1][i] ) ). #include<queue> #i

hdu 5521 Meeting(最短路)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5521 题意:有1-n共n个点,给出m个块(完全图),并知道块内各点之间互相到达花费时间均为ti.已知两人分别在点1和点n,求在哪些点相遇能使得花费时间最短.题解:显然先想到从点1和点n分别求最短路,然后枚举点找出哪些点是相遇花费时间最少的.但是这题边太多了,假设一个完全图里有x个点,那边就有x*(x-1)/2条了,必须化简其边.一个可行的办法是给每个完全图增加两个点,分别为入点和出点,入点向其中的点

【HDU5521】Meeting

题目大意:给定一张\(N\)个点的图,构成了\(M\)个团,每个团内的边权均相等,求图上有多少个点满足到\(1\)号节点和\(N\)号节点的最大值最小. 题解: 本题的核心是如何优化连边,考虑对于每一个团增加一个虚拟节点,并让每个节点到虚拟节点连一条边权为\(t_i\)的有向边,虚拟节点到团中每一个点连一条边权为\(0\)的有向边,最后跑最短路求解即可. 注意:数据中有\(0\)下标的节点,读入时需要忽略,别问我怎么知道的... 代码如下 #include <bits/stdc++.h> us

HDU 5521 Meeting(好题,最短路,2015ACM/ICPC亚洲区沈阳站)

1 /** 2 题意:有n个点,m个集合 3 集合内的点 两两 到的时间为 ti; 4 有两个人 在1,n; 输出最小相遇时间,以及哪些点(可以走走停停); 5 6 思路:****将集合抽象为点.访问过的集合不再访问. 7 Set集合抽象的点. 8 Belong属于哪个集合. 9 */ 10 #include<bits/stdc++.h> 11 using namespace std; 12 typedef long long ll; 13 const ll INF = 0x7f7f7f7f;

【最短路】Walls

Description In a country, great walls have been built in such a way that every great wall connects exactly two towns. The great walls do not cross each other. Thus, the country is divided into such regions that to move from one region to another, it