zoukankan      html  css  js  c++  java
  • 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
    ", 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
    ");
    74         }
    75         else {
    76             int f = 0;
    77             printf("%lld
    ", 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
  • 相关阅读:
    数据库中的索引结构是什么?
    什么情况下适合建立索引?
    python requests https 访问出错
    Centos下 自动化配置SSH免密码登陆
    expect 批量增加用户及配置密码
    Shell 处理文件名中包含空格的文件
    Linux sort 命令
    ictclas bug修复
    [转]hadoop2.x常用端口
    在服务器上运行Jar包
  • 原文地址:https://www.cnblogs.com/GraceSkyer/p/8723943.html
Copyright © 2011-2022 走看看