题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5521

题目大意:

有 \(n\) 个点 \(m\) 个集合,一个点可能处于若干个集合内,属于第 \(i\) 个集合的任意两点间的距离是 \(t_i\) ,点 \(1\) 是起点,点 \(n\) 是终点。

你现在需要找到所有点中到 \(1\) 、 \(n\) 两点的距离的较大值的最小值,并输出所有满足要求的点。

解题思路:

这道题目难的不是最短路,而是建图。

因为最多可能有 \(n\) 个点在同一个集合,而 \(n \le 2 \times 10^5\) ,所以两两之间建边显然是不可取的,所以我们需要采用另一种方式建图:

为每一个集合对应一个点,第 \(i\) 个集合对应点 \(n+i\) ,然后从 \(n+i\) 连向所有第 \(i\) 个集合中的点一条权值为 \(t_i\) 的有向边,从第 \(i\) 个集合中的所有点连向点 \(n+i\) 一条权值为 \(0\) 的边。然后分别以点 \(1\) 和点 \(n\) 为起点求两边最短路。

实现代码如下:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 200020;
int T, n, m, e, dist1[maxn], dist2[maxn];
bool inq[maxn];
struct Node {
int v, w;
Node () {};
Node (int _v, int _w) { v = _v; w = _w; }
};
vector<Node> g[maxn];
queue<int> que;
vector<int> ans_vec;
// 一共n+m个点
void init() {
for (int i = 1; i <= n+m; i ++) g[i].clear();
}
void spfa(int st, int dist[]) {
memset(dist, -1, sizeof(int)*(1+n+m));
memset(inq, 0, sizeof(inq));
while (!que.empty()) que.pop();
dist[st] = 0;
que.push(st);
while (!que.empty()) {
int u = que.front();
que.pop();
inq[u] = false;
int sz = g[u].size();
for (int i = 0; i < sz; i ++) {
int v = g[u][i].v, w = g[u][i].w;
if (dist[v] == -1 || dist[v] > dist[u] + w) {
dist[v] = dist[u] + w;
if (!inq[v]) {
inq[v] = true;
que.push(v);
}
}
}
}
}
int main() {
scanf("%d", &T);
for (int cas = 1; cas <= T; cas ++) {
scanf("%d%d", &n, &m);
init();
for (int i = 1; i <= m; i ++) {
int t, s, u;
scanf("%d%d", &t, &s);
while (s --) {
scanf("%d", &u);
g[n+i].push_back(Node(u, t));
g[u].push_back(Node(n+i, 0));
}
}
spfa(1, dist1);
spfa(n, dist2);
int ans = -1;
for (int i = 1; i <= n; i ++)
if (dist1[i] != -1 && dist2[i] != -1 && (ans==-1 || ans > max(dist1[i], dist2[i])))
ans = max(dist1[i], dist2[i]);
printf("Case #%d: ", cas);
if (ans == -1) puts("Evil John");
else {
printf("%d\n", ans);
ans_vec.clear();
for (int i = 1; i <= n; i ++) if (dist1[i] != -1 && dist2[i] != -1 && max(dist1[i], dist2[i])==ans)
ans_vec.push_back(i);
int sz = ans_vec.size();
for (int i = 0; i < sz; i ++) {
if (i) putchar(' ');
printf("%d", ans_vec[i]);
}
puts("");
}
}
return 0;
}

HDU5521 Meeting 题解 最短路的更多相关文章

  1. HDU5521 Meeting(dijkstra+巧妙建图)

    HDU5521 Meeting 题意: 给你n个点,它们组成了m个团,第i个团内有si个点,且每个团内的点互相之间距离为ti,问如果同时从点1和点n出发,最短耗时多少相遇 很明显题目给出的是个无负环的 ...

  2. [JZOJ5279]香港记者题解--最短路图

    [JZOJ5279]香港记者题解--最短路图 题目链接 过 于 暴 力 分析 有一个naiive的想法就是从1到n跑最短路,中途建图,然后在图上按字典序最小走一遍,然而·这是不行的,你这样跳不一定能跳 ...

  3. hdu-5521 Meeting(最短路)

    题目链接: Meeting Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) ...

  4. hdu5521(Meeting)spfa 层次网络最短路

    题意:给出几个集合,每个集合中有Si个点 且任意两个点的距离为ti,现在要求两个人分别从1和n出发,问最短多长时间才能遇到,且给出这些可能的相遇点; 取两个人到达某点时所用时间大的值 然后取最小的   ...

  5. [hdu5521 Meeting]最短路

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

  6. URAL 1085 Meeting(最短路)

    Meeting Time limit: 2.0 secondMemory limit: 64 MB K friends has decided to meet in order to celebrat ...

  7. hdu 5521 Meeting(最短路)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5521 题意:有1-n共n个点,给出m个块(完全图),并知道块内各点之间互相到达花费时间均为ti.已知两 ...

  8. hdu5521 Meeting

    传送门 题目 Bessie and her friend Elsie decide to have a meeting. However, after Farmer John decorated hi ...

  9. HDU 5521:Meeting(最短路)

    http://acm.hdu.edu.cn/showproblem.php?pid=5521 Meeting Problem Description   Bessie and her friend E ...

随机推荐

  1. Eclipsed的SVN插件不能识别之前工作空间的项目

    今天用Eclipse的SVN插件,由于之前项目是用"tortoisesvn"进行checkout的,并且已经在工作空间中使用.后来用来Ecplise的SVN插件,可是发现右键Tea ...

  2. 2012-4-2 通过MdiParent设置窗体最前

    SentenceForm form = new SentenceForm(); form.MdiParent = this; form.Show(); //form.MdiParent = this; ...

  3. HTML静态网页--JavaScript-简介

    JavaScript简介 1.JavaScript是个什么东西? 它是个脚本语言,需要有宿主文件,它的宿主文件是HTML文件. 2.它与Java什么关系? 没有什么直接的联系,Java是Sun公司(已 ...

  4. 使用属性position:fixed的时候如何才能让div居中

    css: .aa{ position: fixed; top: 200px; left: 0px; right: 0px; width: 200px; height: 200px; margin-le ...

  5. [C++] 自动关闭右下角弹窗

    最近腾讯.迅雷等各种客户端,都越发喜欢在屏幕的右下角弹框了. 有骨气的人当然可以把这些软件卸载了事,但是这些客户端在某些情况下却又还是有用的.怎么办呢? 作为码农,自己实现一个自动关闭右下角弹窗的程序 ...

  6. Python--day42--mysql创建用户及授权

    1,打开mysql数据库命令:mysql -u root -p 2,创建数据库create database db2; 2,删除数据库drop database db2; 2,展示有多少个文件夹:sh ...

  7. npm install 报错(npm ERR! errno -4048,Error: EPERM: operation not permitted)

    问题现象 原因 1.初次看报错日志内容,定义权限为问题,后来查资料才知道是缓存问题. 解决方法 1.简单直接 直接删除 npmrc文件 tips: 不是nodejs安装目录npm模块下的那个npmrc ...

  8. P1067 叠罗汉

    题目描述 茜茜和聪聪是关系很好的同桌,有一天,茜茜觉得天空中的白云像棉花糖一样,应该很好吃吧,但是够不着,她很烦恼. 聪聪为了帮助茜茜解决烦恼,决定帮他把天空中的白云摘下来做成棉花糖给她吃. 但是聪聪 ...

  9. P1059 硬币翻转

    题目描述 从前有很多个硬币摆在一行,有正面朝上的,也有背面朝上的.正面朝上的用1表示,背面朝上的用0表示.现在要求从这行的第一个硬币开始,将前若干个硬币一起翻面,问如果要将所有硬币翻到正面朝上,最少要 ...

  10. 使用 node.js三行代码实现手机端访问html页面文件

    首先确保你安装了node (全局安装) npm install -g browser-sync // --files 路径是相对于运行该命令的项目(目录) browser-sync start --s ...