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

学习菊苣的博客,只粘链接,不粘题目描述了。

题目大意就是一个人从1开始走,一个人从n开始走。让最后相遇的时间最短。

题目就是个最短路,不过唯一不同的是,题目图的描述方式比较特别。

从规模上来看,想把这张图描述成邻接矩阵或者邻接表是不可能的。

必然只能按照题目要求的意思来存。

于是第一步存图的方式,我采用了两个vector数组,(当然此处可以使用链式前向星),一个存了和点相关的集合有哪些in[],即这个点包含在哪些集合里面;一个存了集合里面有哪些点edge[]。

然后就是跑两遍最短路了,这里我采用了优先队列的spfa(貌似就是优先队列的dijikstra)。

不过直接这样上去T了好多发。

然后考虑到用了优先队列后,相当于优化了这个dp的过程,让每个点只需要遍历一次。那么,自然而然的,如果i遍历了集合s里面的所有点,自然集合s也只需要遍历一次。加了这一个剪枝就能AC了。由于遍历集合的时候,不是按照从最小权值集合开始的,所以这里没有对队列里面的元素进行判重,不过影响不是很大。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <set>
#include <queue>
#include <vector>
#define LL long long using namespace std; struct node
{
int id, val;
bool operator<(const node x) const
{
return val>x.val;
}
};
const int maxN = ;
const int maxM = ;
int n, m;
vector<int> in[maxN];
int dis[maxM];
vector<int> edge[maxM];
LL p[][maxN];
bool vis[maxM]; void input()
{
scanf("%d%d", &n, &m);
int t, s, k;
for (int i = ; i < m; ++i)
{
scanf("%d%d", &t, &s);
dis[i] = t;
for (int j = ; j < s; ++j)
{
scanf("%d", &k);
in[k].push_back(i);
edge[i].push_back(k);
}
}
memset(p, -, sizeof(p));
} void spfa(int from, int x)
{
memset(vis, false, sizeof(vis));
priority_queue<node> q;
node k, t;
int w, u, v;
k.id = from;
k.val = ;
q.push(k);
p[x][from] = ;
while (!q.empty())
{
k = q.top();
q.pop();
u = k.id;
for (int i = ; i < in[u].size(); ++i)
{
w = in[u][i];
if (vis[w]) continue;
for (int j = ; j < edge[w].size(); ++j)
{
v = edge[w][j];
if (u == v) continue;
if (p[x][v] == - || p[x][v] > p[x][u]+dis[w])
{
p[x][v] = p[x][u]+dis[w];
t.id = v;
t.val = p[x][v];
q.push(t);
}
}
vis[w] = true;
}
}
} LL myMin(LL x, LL y)
{
if (x == -) return y;
else return min(x, y);
} void work()
{
spfa(, );
spfa(n, );
LL mi = -;
for (int i = ; i <= n; ++i)
if (p[][i] != - && p[][i] != -)
mi = myMin(mi, max(p[][i], p[][i]));
if (mi == -)
{
printf("Evil John\n");
return;
}
printf("%d\n", mi);
bool flag = false;
for (int i = ; i <= n; ++i)
if (p[][i] != - && p[][i] != - && mi == max(p[][i], p[][i]))
{
if (flag) printf(" ");
printf("%d", i);
flag = true;
}
printf("\n");
} void clss()
{
for (int i = ; i < m; ++i)
edge[i].clear();
for (int i = ; i <= n; ++i)
in[i].clear();
} int main()
{
//freopen("test.in", "r", stdin);
int T;
scanf("%d", &T);
for (int times = ; times < T; ++times)
{
printf("Case #%d: ", times+);
input();
work();
clss();
}
return ;
}

ACM学习历程—HDU5521 Meeting(图论)的更多相关文章

  1. 完成了C++作业,本博客现在开始全面记录acm学习历程,真正的acm之路,现在开始

    以下以目前遇到题目开始记录,按发布时间排序 ACM之递推递归 ACM之数学题 拓扑排序 ACM之最短路径做题笔记与记录 STL学习笔记不(定期更新) 八皇后问题解题报告

  2. ACM学习历程—HDU 5512 Pagodas(数学)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5512 学习菊苣的博客,只粘链接,不粘题目描述了. 题目大意就是给了初始的集合{a, b},然后取集合里 ...

  3. ACM学习历程—HDU2476 String painter(动态规划)

    http://acm.hdu.edu.cn/showproblem.php?pid=2476 题目大意是给定一个起始串和一个目标串,然后每次可以将某一段区间染成一种字符,问从起始串到目标串最少需要染多 ...

  4. ACM学习历程—HDU5700 区间交(树状数组 && 前缀和 && 排序)

    http://acm.hdu.edu.cn/showproblem.php?pid=5700 这是这次百度之星初赛2B的第五题.省赛回来看了一下,有这样一个思路:对于所有的区间排序,按左值排序. 然后 ...

  5. ACM学习历程—HDU5701 中位数计数(中位数 && 计数排序)

    http://acm.hdu.edu.cn/showproblem.php?pid=5701 这是这次百度之星初赛2B的第六题.之前白山云做过类似的题,省赛完回来,我看了一下大概就有这样的思路:首先枚 ...

  6. ACM学习历程—HDU5696 区间的价值(分治 && RMQ && 线段树 && 动态规划)

    http://acm.hdu.edu.cn/showproblem.php?pid=5696 这是这次百度之星初赛2B的第一题,但是由于正好打省赛,于是便错过了.加上2A的时候差了一题,当时有思路,但 ...

  7. ACM学习历程—HDU5668 Circle(数论)

    http://acm.hdu.edu.cn/showproblem.php?pid=5668 这题的话,假设每次报x个,那么可以模拟一遍, 假设第i个出局的是a[i],那么从第i-1个出局的人后,重新 ...

  8. ACM学习历程—HDU5667 Sequence(数论 && 矩阵乘法 && 快速幂)

    http://acm.hdu.edu.cn/showproblem.php?pid=5667 这题的关键是处理指数,因为最后结果是a^t这种的,主要是如何计算t. 发现t是一个递推式,t(n) = c ...

  9. ACM学习历程—HDU5666 Segment(数论)

    http://acm.hdu.edu.cn/showproblem.php?pid=5666 这题的关键是q为质数,不妨设线段上点(x0, y0),则x0+y0=q. 那么直线方程则为y = y0/x ...

随机推荐

  1. lua(仿类)

    Account = { balance = } function Account:deposit(v) self.balance = self.balance + v end function Acc ...

  2. EhCache 集群 配置(RMI方式)

    这里先说明下环境:JDK1.6.ehcache-core-2.1.0.jar.Tomcat6.Spring3.0.2.使用的是RMI方式配置集群的,这里先吐槽下遇到的情况,在搜相关知识的时候发现到处都 ...

  3. netstat命令简单使用

    1.适用范围 该命令用于打印网络连接.路由表.接口统计.伪装连接.多播成员等信息. (netstat已经过时,现在使用ss命令,所以本文不会作过多翻译,只着重一些重要部分) 2.语法概览 netsta ...

  4. JAVA NIO 简介 (netty源码死磕1.1)

    [基础篇]netty 源码死磕1.1:  JAVA NIO简介 1. JAVA NIO简介 Java 中 New I/O类库 是由 Java 1.4 引进的异步 IO.由于之前老的I/O类库是阻塞I/ ...

  5. word2vec_basic.py

    ssh://sci@192.168.67.128:22/usr/bin/python3 -u /home/win_pymine_clean/feature_wifi/word2vec_basic.py ...

  6. OC中第三方库MJExtension的使用

    MJExtension是一套常用的"字典和模型之间互相转换"的框架,在项目中也使用过,现在记录一下.随着Swift的普及,在Swift中也有一个类似功能的框架HandyJSON 也 ...

  7. JavaScript-Confirm用法

    function checkMobileBind() {    if(confirm('您尚未绑定手机,是否前往绑定?'))    {        window.location='http://m ...

  8. [APIO2008]免费道路

    [APIO2008]免费道路 BZOJ luogu 先把必须连的鹅卵石路连上,大于k条no solution 什么样的鹅卵石路(u,v)必须连?所有水泥路都连上仍然不能使u,v连通的必须连 补全到k条 ...

  9. Android系统移植与调试之------->如何修改Android设备添加重启、飞行模式、静音模式等功能(二)

    今天要说的是为Android设备添加重启.飞行模式.静音模式按钮,客户需求中需要添加这项功能,在长按电源键弹出的菜单中没有这些选项,谨以此文记录自己添加这个功能的过程. 首先找到长按电源键弹出的对话框 ...

  10. OOP中的逆变和协变

    逆变和协变在存在于强类型语言中,尽管非常少提及.可是里面蕴含了面向对象的世界观.感谢和我一起讨论这个问题的人. 这里用了C#.Scala的语法作为演示样例.事实上逆变和协变的概念跟语言本身关系不大.事 ...