题目描述:

给定一张图,问从1和n相遇的最短时间。

这道题的输入比较特殊,不能直接存,所以怎么输入,怎么存取,只要可以访问到一个节点的相邻节点就可以,由于spfa算法的时间复杂度为m*n,而Dijkstra算法的时间复杂度为m*log(n),

其实Dijkstra就是用优先队列替换掉了spfa中的普通队列,每次都是用权值最小的点去更新别人,可以这么理解,用用权值最小的点a去更新其他节点,在更新节点中必然会有一个节点已经是

最短路,假设是b,因为源点到其他节点的距离+其他节点到b节点的距离 >  dist[a] + edge[a][b], 因为 源点到其他节点的距离 > dist[a] + edge[a][b];最多有10^6个点,那么可能就会有 10^12条边 ,时间复杂度为 10^12 * log(10^5) = 15*10^12;所以主要取决于有多少条边,分析一下如果一个节点已经更新了它所在集合中的其他点,那么这个集合中所有点之间的边就不会在更新了,假设a,b,c,d,e在一个集合里,集合之间的路径为edge,假设a是更新点,说明b,c,d,e的最短路大于a的最短路, 说明b,c,d的最短路一定是由a得到,而不是 b,c,d,Dis[a]+edge < Dist[k] +edge,k属于b,c,d。所以集合只会被访问一次。

//有可能一个人在家等他
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#include <algorithm>
#include <math.h>
#define maxn 1100000
#define LL long long
using namespace std;
int t;
int n,m;
vector < int > G[maxn];
int tt[maxn],ss[maxn];
vector < int > Set[maxn];
LL Dist[][maxn];
int vis[maxn];
int VISIT[maxn];
LL answer[maxn];
LL ans[maxn];
struct node
{
int u,dist;
friend bool operator < (node a,node b)
{
return a.dist>b.dist;
}
};
void init()
{
memset(vis,,sizeof(vis));
memset(VISIT,,sizeof(VISIT));
} void Dijkstra(int start)
{
int kind;
if(start==)
kind=;
else
kind=;
priority_queue < node > que;
node s;
s.u=start;
s.dist=;
Dist[kind][start]=;
que.push(s);
while(!que.empty())
{
s=que.top();
que.pop();
if(vis[s.u]==)
continue;
vis[s.u]=;
int from=s.u;
for(int i=;i<Set[from].size();i++) //找到所在集合
{
int j=Set[from][i]; //j代表哪个集合
if(VISIT[j]==)
continue;
VISIT[j]=;
int edge= tt[j]; //edge代表长度
for(int k=;k<G[j].size();k++) //遍历相邻节点
{
node Next;
int to=G[j][k];
if(Dist[kind][to]>Dist[kind][from]+edge || Dist[kind][to]==- )
{
Dist[kind][to]=Dist[kind][from] + edge;
Next.dist=Dist[kind][to];
Next.u=to;
que.push(Next);
}
}
}
}
} void solve()
{
init();
Dijkstra();
init();
Dijkstra(n);
for(int i=;i<=n;i++)
{
// cout<<Dist[1][i]<<" "<<Dist[2][i]<<endl;
if(Dist[][i]==- || Dist[][i]==-)
answer[i]=-;
else
answer[i]=max(Dist[][i],Dist[][i]);
}
LL MIN=-;
for(int i=;i<=n;i++)
{
if(MIN > answer[i] || (MIN==-) )
MIN=answer[i];
}
if(MIN==-)
printf("Evil John\n");
else
{
printf("%I64d\n",MIN);
int flag=;
for(int i=;i<=n;i++)
{
if(MIN==answer[i])
{
if(flag==)
printf(" ");
printf("%d",i);
flag=;
}
} printf("\n");
}
}
void input()
{
scanf("%d%d",&n,&m);
for(int i=;i<=m;i++)
{
scanf("%d%d",&tt[i],&ss[i]);
for(int j=;j<=ss[i];j++)
{
int input;
scanf("%d",&input);
G[i].push_back(input);
Set[input].push_back(i);
}
}
}
void Init()
{
for(int i=;i<maxn;i++)
{
G[i].clear(); Set[i].clear();
}
memset(Dist,-,sizeof(Dist));
}
int main()
{
//freopen("test.txt","r",stdin);
scanf("%d",&t);
int Case=;
// printf("%d\n",inf);
// cout<<inf<<endl;
while(t--)
{
Init();
input();
printf("Case #%d: ",++Case);
solve();
}
return ;
}

hdu5521 ( Dijkstra )的更多相关文章

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

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

  2. Dijkstra 单源最短路径算法

    Dijkstra 算法是一种用于计算带权有向图中单源最短路径(SSSP:Single-Source Shortest Path)的算法,由计算机科学家 Edsger Dijkstra 于 1956 年 ...

  3. 最短路径算法-Dijkstra

    Dijkstra是解决单源最短路径的一般方法,属于一种贪婪算法. 所谓单源最短路径是指在一个赋权有向图中,从某一点出发,到另一点的最短路径. 以python代码为例,实现Dijkstra算法 1.数据 ...

  4. [板子]最小费用最大流(Dijkstra增广)

    最小费用最大流板子,没有压行.利用重标号让边权非负,用Dijkstra进行增广,在理论和实际上都比SPFA增广快得多.教程略去.转载请随意. #include <cstdio> #incl ...

  5. POJ 2253 Frogger(Dijkstra)

    传送门 Frogger Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 39453   Accepted: 12691 Des ...

  6. POJ 2387 Til the Cows Come Home(最短路 Dijkstra/spfa)

    传送门 Til the Cows Come Home Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 46727   Acce ...

  7. Dijkstra 算法

    all the nodes should be carectorized into three groups: (visited, front, unknown) we should pay spec ...

  8. 51nod 1459 迷宫游戏 (最短路径—Dijkstra算法)

    题目链接 中文题,迪杰斯特拉最短路径算法模板题. #include<stdio.h> #include<string.h> #define INF 0x3f3f3f3f ],v ...

  9. 51nod1459(带权值的dijkstra)

    题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1459 题意:中文题诶- 思路:带权值的最短路,这道题数据也没 ...

随机推荐

  1. [HDU5919]Sequence II

    [HDU5919]Sequence II 试题描述 Mr. Frog has an integer sequence of length n, which can be denoted as a1,a ...

  2. 洛谷P2057 善意的投票

    题目描述 幼儿园里有n个小朋友打算通过投票来决定睡不睡午觉.对他们来说,这个问题并不是很重要,于是他们决定发扬谦让精神.虽然每个人都有自己的主见,但是为了照顾一下自己朋友的想法,他们也可以投和自己本来 ...

  3. BZOJ1693: [Usaco2007 Demo]Asteroids

    n<=500 *n的格子,给m<=10000个格子有人,一炮可以清掉一行或一列的人(莫名的爽!)求最少几炮干掉所有人. 经典二分图模型!行成点,列成点,一个点就连接一行一列,表示这一行或这 ...

  4. BZOJ1742: [Usaco2005 nov]Grazing on the Run 边跑边吃草

    数轴上n<=1000个点,从p出发以任意顺序走到所有的点,求到达每个点的时间之和的最小值. 好题!看起来水水的实际易错! 显然的结论是经过一个区间点之后肯定落在左端点或右端点上,谁没事最后还往中 ...

  5. 微服务架构的基础框架选择:Spring Cloud还是Dubbo?

    本文转自:http://mt.sohu.com/20160803/n462486707.shtml 最近一段时间不论互联网还是传统行业,凡是涉及信息技术范畴的圈子几乎都在讨论 微服务架构 .近期也看到 ...

  6. 2018 ACM 国际大学生程序设计竞赛上海大都会赛重现赛 A,D

    A链接:https://www.nowcoder.com/acm/contest/163/A Fruit Ninja is a juicy action game enjoyed by million ...

  7. 【小记事】解除端口占用(Windows)

    开发中有时会因为端口占用而导致起项目时报错(如下图),这时候只要解除端口占用即可. 解除端口占用: 1.打开cmd(win+r),查看端口占用情况 netstat -ano | findstr 端口号 ...

  8. 海康设备网络SDK 编程

    http://www.cnblogs.com/qtblog/p/5366276.html http://www.hikvision.com/Cn/download_more_401.html

  9. dubbo-admin安装和使用

    更新下链接,不知道是不是这个项目合入Apache的缘故,链接都变成了https://github.com/apache/incubator-dubbo/ 按照常理,直接去 https://github ...

  10. JAVA学习(一):Java介绍及其平台、开发环境的配置与搭建

    Java介绍及其平台.开发环境的配置与搭建 1.Java的介绍 Java是一种面向对象的编程语言,具有跨平台.可移植.分布式.简单.可扩展等诸多特性.Java能够进行桌面应用.Web应用.分布式系统及 ...