码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 5521 Meeting

时间:2015-10-31 21:36:35      阅读:362      评论:0      收藏:0      [点我收藏+]

标签:

 

每个点向他所在集合连一条权为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 = 0x3f3f3f3f3f3f3f3fLL;
struct Edge
{
    int v;
    int w;
    int nxt;
    Edge() {}
    Edge(int vv, int ww, int Nxt = -1) { v = vv , w = ww, nxt = Nxt; }
} e[M << 2];
int head[M], mm;
void initEdge() { mm = 0; memset(head, -1, sizeof head); }
void adde(int u, int v, int w)
{
    swap(u, v);
    e[mm] = Edge(v, w, head[u]);
    head[u] = mm ++;
}
vector<int> g[M];
int n, m;
LL d1[ M], d2[ M];
struct Heap
{
    LL d; int u;
    Heap() {}
    Heap(LL dd, int uu) { d = dd, u = uu; }
    bool operator < (const Heap& rhs) const {
        return d > rhs.d;
    }
};
bool done[M];
void Dij(int src, LL d[])
{
    priority_queue<Heap> Q;
    memset(d, 0x3f, sizeof d);
    for (auto x: g[src]) {
        d[x + n] = 0;
        Q.push(Heap(0, x + n));
    }
    Q.push(Heap(0, src));
    d[src] = 0;
    memset(done, false, sizeof done);
    while (!Q.empty()) {
        Heap x = Q.top(); Q.pop();
        int u = x.u;
        if (done[u]) continue;
        done[u] = true;
        for (int i=head[u];~i;i=e[i].nxt) {
            LL w = e[i].w;
            int v = e[i].v;
            if (d[v] > d[u] + w) {
                d[v] = d[u] + w;
                Q.push(Heap(d[v], v));
            }
        }
    }
}
int main()
{
    int re, ca=1; scanf("%d", &re);
    while (re-- ) {
        scanf("%d%d", &n, &m);
        initEdge();
        for (int i=1;i<=n;i++) g[i].clear();
        for (int i=1;i<=m;i++) {
            int cost, k;
            scanf("%d%d", &cost, &k);
            while (k -- ) {
                int x; scanf("%d", &x);
                adde(i + n, x, cost);
                g[x].push_back(i);
            }
        }
        for (int i=1;i<=n;i++) for (int j : g[i])
            adde(i, j+n, 0);
        memset(d1, 0x3f, sizeof d1);
        memset(d2, 0x3f, sizeof d2);
        Dij(1, d1);
        Dij(n, d2);
        LL ans = inf;
        for (int i=1;i<=n;i++) {
            ans = min(ans, max(d1[i], d2[i]));
        }
        vector<int> vec;
        printf("Case #%d: ", ca++);
        if (ans >= inf) { puts("Evil John"); continue; }
        printf("%I64d\n", ans);
        for (int i=1;i<=n;i++) if (ans == max(d1[i], d2[i])) {
            vec.push_back(i);
        }
        for (int i=0;i<vec.size();i++)
            printf("%d%c", vec[i], i==vec.size()-1 ? 10 : ‘ ‘);
    }
}

  

HDU 5521 Meeting

标签:

原文地址:http://www.cnblogs.com/oilover/p/4926231.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!