思路:

看了好久才看懂题意,文中给了n个点,有m个集合,每个集合有s个点,集合内的每两个点之间有一个权值为t的边,现在有两个人,要从1号点,和n号点,走到同一个顶点,问最少花费以及花费最少的点。

那就直接跑两遍最短路,然后枚举每一点,取最短路最大值最小的点。

然而这么浅显的做法却MLE啦,真是用心险恶的出题人呀。

其实仔细想一想就知道了,题目的要求是,每个集合里面,都是一个完全图,如果只有一个集合,那么2e5个点,边的条数就是4e10条,爆内存简直是必然的。所以需要在建图的时候优化,或者是换一种算法。如果要在建图的时候优化,那么就要忽视那些,在集合内,却没有与其他集合相连的点。如何找出这些点呢?很容易想到,如果一个点在输入的数据中出现了两次或以上,那么它一定是与其他集合有关的,但是如何记录这些点是一个很大的问题。如果用数组记录下每个集合有哪些点,或者每个点属于哪些集合,很明显都是不行的,但是如果使用vector呢?既然题目中已经提到了,s的和不会超过1e6,那么这样或许是可行的。我首先尝试了一下,记录下每个集合有哪些点。

然而还是炸了内存。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

自闭。

回来再想一想,好像还是没有最开始的完全图问题,因为这数据可以有两个集合,而这两个集合都是满的。。。。。(好歹毒呀)

最后我还是无耻得看了一下其他人的题解.了解了一种可以大幅减少完全图的边数.方法就是,在每一个完全图的边上,建一个虚拟点,让每一点去虚拟点的距离就是t,回来是0.如果是一般情况,也就是说,点到点之间的距离不相等的话,这个方法貌似就无法使用啦.

代码:

  1. #include<iostream>
  2. #include<algorithm>
  3. #include<vector>
  4. #include<queue>
  5. #include<deque>
  6. #include<stack>
  7. #include<map>
  8. #include<set>
  9. #include<cstdio>
  10. #include<cstring>
  11. #include<cmath>
  12. #include<cstdlib>
  13. #define fuck(x) cout<<#x<<" = "<<x<<endl;
  14. using namespace std;
  15. typedef long long ll;
  16. typedef unsigned long long ull;
  17. const int maxn = ;
  18. const int inf = 1.0e9+;
  19. const ll INF = ;
  20. const double eps = 1e-;
  21.  
  22. int n,m;
  23. ll diss1[maxn],diss2[maxn];
  24. int num[maxn];
  25. vector<int>u[maxn];
  26. vector<ll>w[maxn];
  27. bool book[*maxn];
  28. void init()
  29. {
  30. for(int i=;i<=n*;i++){
  31. u[i].clear();
  32. w[i].clear();
  33. diss1[i]=diss2[i]=INF;
  34. }
  35. }
  36.  
  37. struct node
  38. {
  39. int x;
  40. ll s;
  41. bool operator<(const node p)const{return p.s<s;}
  42. };
  43. int Dijkstra(int sx,ll *dis)
  44. {
  45. memset(book,,sizeof(book));
  46. dis[sx]=0ll;
  47. priority_queue<node>q;
  48. node exa;
  49. exa.x=sx;
  50. exa.s=0ll;
  51. q.push(exa);
  52. while(!q.empty()){
  53. exa=q.top();q.pop();
  54. if(book[exa.x]){continue;}
  55. book[exa.x]=true;
  56. int t=exa.x;
  57. int siz=u[t].size();
  58. for(int i=;i<siz;i++){
  59. if(dis[u[t][i]]>dis[t]+w[t][i]){
  60. dis[u[t][i]]=dis[t]+w[t][i];
  61. exa.s=dis[u[t][i]];
  62. exa.x=u[t][i];
  63. q.push(exa);
  64. }
  65. }
  66. }
  67. }
  68.  
  69. int main()
  70. {
  71. // ios::sync_with_stdio(false);
  72. // freopen("in.txt","r",stdin);
  73.  
  74. int T;
  75. scanf("%d",&T);
  76. int cases = ;
  77. while(T--){
  78. cases++;
  79. scanf("%d%d",&n,&m);
  80. init();
  81. for(int i=;i<=m;i++){
  82. int ss;
  83. ll t;
  84. scanf("%lld%d",&t,&ss);
  85. for(int j=;j<=ss;j++){
  86. scanf("%d",&num[j]);
  87. }
  88. for(int j=;j<=ss;j++){
  89. u[num[j]].push_back(n+i);
  90. w[num[j]].push_back(t);
  91. u[n+i].push_back(num[j]);
  92. w[n+i].push_back();
  93. }
  94. }
  95.  
  96. Dijkstra(,diss1);
  97. Dijkstra(n,diss2);
  98.  
  99. ll ans = INF;
  100. for(int i=;i<=n;i++){
  101. diss1[i]=max(diss1[i],diss2[i]);
  102. ans=min(ans,diss1[i]);
  103. }
  104.  
  105. printf("Case #%d: ",cases);
  106. if(ans ==INF){printf("Evil John\n");continue;}
  107. else printf("%lld\n",ans);
  108. vector<int>anss;
  109. for(int i=;i<=n;i++){
  110. if(ans==diss1[i]){anss.push_back(i);}
  111. }
  112. int siz = anss.size();
  113. for(int i=;i<siz-;i++){
  114. printf("%d ",anss[i]);
  115. }
  116. printf("%d\n",anss[siz-]);
  117. }
  118.  
  119. return ;
  120. }

∑mi=1Si≤10

HDU - 5521 Meeting (Dijkstra)的更多相关文章

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

    Meeting Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Total ...

  2. HDU 5521.Meeting 最短路模板题

    Meeting Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total ...

  3. HDU 5521 Meeting【最短路】

    今天旁观了Angry_Newbie的模拟区域赛(2015shenyang) 倒着看最先看的M题,很明显的最短路问题,在我看懂的时候他们已经开始敲B了. 后来听说D过了很多人.. D题一看是个博弈,给了 ...

  4. hdu 5521 Meeting(最短路)

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

  5. HDU 5521 Meeting (最短路,dijstra)

    题意:有N个点,两个人,其中一个人住在点1,另一个人住在点n,有M个点集,集合内的数表示任意两点的距离为dis ,现在问,如果两个人要见面, 需要最短距离是多少,有哪几个点能被当成见面点. 析:分别对 ...

  6. HDU 5521 Meeting

    2015 ACM / ICPC 沈阳站现场赛 M题 最短路 设置N+M个节点,前N个节点是Block,后M个节点是Set,每一组Set中的点向该Set连边,从1和n开始分别求最短路.注意爆int. # ...

  7. HDU 5521:Meeting(最短路)

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

  8. hdu 5521 最短路

    Meeting Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total ...

  9. Meeting HDU - 5521 虚点建图

    Problem Description Bessie and her friend Elsie decide to have a meeting. However, after Farmer John ...

随机推荐

  1. 神烦之float

    另外一篇文章 : css float 一 历史 Float的设计初衷仅仅是:文字环绕效果(向word中的文字环绕效果) 二 特性 1.包裹性:块级元素如果不设置float,它默认会撑满整个屏幕,而如果 ...

  2. 错误代码 0x800700b7 配置错误定义了重复的“system.web.extensions/scripting/scriptResourceHandler”节

    如果是运行VS时就报错,改个端口号就可以解决问题,改完以下两个地方重新运行

  3. 22Java之JDBCTemplate总结

    写在前面:这里总结4种方式来操作数据库(SE阶段) 一.JDBC         JDBC有关的类:都在java.sql 和 javax.sql 包下.   1.数据准备               ...

  4. Python面试题练习

    1.实现1--100之和 #解答一 print sum(xrange(101)) #解答二 s=0 for i in xrange(101): s = s + i print s 2.如何在一个函数内 ...

  5. Awesome-3d

    1.素描-你的3D内容在网络,移动,AR,和虚拟现实. 2.跨平台AR SDK =======================

  6. 【BZOJ 1701】Cow School(斜率优化/动态凸包/分治优化)

    原题题解和数据下载 Usaco2007 Jan 题意 小牛参加了n个测试,第i个测试满分是\(p_i\),它的得分是\(t_i\).老师去掉\(t_i/p_i\)最小的d个测试,将剩下的总得分/总满分 ...

  7. 【HDU - 4340】Capturing a country(树形DP)

    BUPT2017 wintertraining(15) #8A 题意 n(<100)个城市组成的树.A攻击i城市需要a[i]代价,B需要b[i].如果一个城市的邻居被A攻击了,那么A攻击它只要A ...

  8. centos install redmine (项目管理工具)

    安装环境:Centos.mysql.Ruby.Apache.Redmineyum updateyum -y groupinstall "Development Tools"yum ...

  9. 在浏览器中浏览git上项目目录结构

    效果如下,参考:https://gitee.com/oschina/GitCodeTree

  10. CF1131F Asya And Kittens(Kruskal重构树,启发式合并)

    这题难度1700,我感觉又小了…… 这题虽然没几个人是用kruskal重构树的思想做的,但是我是,所以我就放了个kruskal重构树的标签. 题目链接:CF原网 题目大意:有一个长为 $n$ 的排列, ...