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条了,必须化简其边。一个可行的办法是给每个完全图增加两个点,分别为入点和出点,入点向其中的点连边,其中的点再向出点连边,权均为0,出点向入点连边,权为ti,边数就化简为2*x了。代码实现:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const ll INF = 1e18;
 5 const int N = 2100010;
 6 const int M = 2100010;
 7 struct edge {
 8     int to;
 9     ll cost;
10     edge(int _to, ll _cost):to(_to),cost(_cost){}
11 };
12 typedef pair<ll, int> P;// first是最短距离,second是顶点的编号
13 int V;
14 vector<edge>G[N];
15 ll d[2][N];//点1 和 点n 到达其他点的最短时间
16 void dij(int id, int s) {
17     priority_queue<P, vector<P>, greater<P> > que;
18     for(int i = 0; i <= V; ++i) d[id][i] = INF;
19     d[id][s] = 0;
20     que.push(P(0, s));
21
22     while(!que.empty()) {
23         P p = que.top(); que.pop();
24         int v = p.second;
25         if(d[id][v] < p.first) continue;
26         int num = G[v].size();
27         for(int i = 0; i < num; ++i) {
28             edge e = G[v][i];
29             if(d[id][e.to] > d[id][v] + e.cost) {
30                 d[id][e.to] = d[id][v] + e.cost;
31                 que.push(P(d[id][e.to], e.to));
32             }
33         }
34     }
35 }
36 int main() {
37     int k, T, t, n, m, i, s, x, u, v;
38     scanf("%d", &T);
39     for(k = 1; k <= T; ++k) {
40         for(i = 0; i < N; ++i) G[i].clear();
41         scanf("%d%d", &n, &m);//点数,集合(完全图)数目
42         for(i = 1; i <= 2*m; i += 2) {
43             u = n+i;//入点
44             v = n+i+1;//出点
45             scanf("%d%d", &t, &s);//时间,集合中点数
46             while(s--) {
47                 scanf("%d", &x);
48                 G[u].push_back(edge(x, 0));
49                 G[x].push_back(edge(v, 0));
50             }
51             G[v].push_back(edge(u, t));
52         }
53         V = n+2*m;
54         dij(0, 1);
55         dij(1, n);
56         /*
57         puts("-----------------");
58         for(i = 1; i <= n; ++i) {
59             printf("%lld, %lld\n", d[0][i], d[1][i]);
60         }
61         puts("-----------------");
62         */
63         ll mi = INF;
64         int cnt = 0;
65         ll a = 0;
66         for(i = 1; i <= n; ++i) {
67             if((a = max(d[0][i], d[1][i])) < mi) {
68                 mi = a;
69             }
70         }
71         printf("Case #%d: ", k);
72         if(mi == INF) {
73             printf("Evil John\n");
74         }
75         else {
76             int f = 0;
77             printf("%lld\n", mi);
78             for(i = 1; i <= n; ++i) {
79                 a = max(d[0][i], d[1][i]);
80                 if(a == mi) {
81                     if(f) putchar(‘ ‘);
82                     printf("%d", i);
83                     f = 1;
84                 }
85             }
86             puts("");
87         }
88     }
89     return 0;
90 }

2667ms

原文地址:https://www.cnblogs.com/GraceSkyer/p/8723943.html

时间: 2024-08-03 22:00:31

hdu 5521 Meeting(最短路)的相关文章

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

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(好题,最短路,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;

HDU 5521 Meeting

每个点向他所在集合连一条权为0的边,每个集合向他里面所有点连一条权为c的边,跑最短路就行了. #include <bits/stdc++.h> using namespace std; #define prt(k) cerr<<#k" = "<<k<<endl typedef long long LL; //const int inf = 0x3f3f3f3f; const int M = 2000100; const LL inf =

HDU 5521 [图论][最短路][建图灵感]

/* 思前想后 还是决定坚持写博客吧... 题意: n个点,m个集合.每个集合里边的点是联通的且任意两点之间有一条dis[i]的边(每个集合一个dis[i]) 求同时从第1个点和第n个点出发的两个人相遇的最短时间,并输出相遇的地点,如果有多个按编号大小顺序输出. 输入: 测试数据 t n m 以下m行每行 dis[i] 该集合点的数量 ...每个点的标号 数据范围: n 2-1e5 所有集合的元素的数量和 1e6 思路: 如果直接跑最短路,边会存爆的. 考虑换种思路建边. 每个集合看作两个点,一

hdu 5521 最短路

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

HDU 4311 Meeting point-1 &amp;&amp; HDU 4312 Meeting point-2

这俩个题  题意::给出N(<1e5)个点求找到一个点作为聚会的地方,使每个点到达这里的距离最小.4311是 曼哈顿距离 4312是 切比雪夫距离: 曼哈顿距离 :大家都知道 对于二维坐标系a(xa,yb),b(xb,yb)的曼哈顿距离是abs(xa-xb)+abs(ya-yb): 看的出来这个距离和x,y 都有关,但是X,Y并不相互影响,所以可以分开计算这样,分开计算的好处如下: 如果 只给一个维度的坐标系 ,我们是不可以再什么养的复杂度的时间内处理出来呢? 大难还是很好想的先排序一下,会发现

HDU 2544:最短路( 最短路径入门 &amp;&amp;Dijkstra &amp;&amp; floyd )

最短路 Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 30972    Accepted Submission(s): 13345 Problem Description 在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的t-shirt.但是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候,却是非常累的!所以现在他们想要寻找