HDU 2145 zz's Mysterious Present 【多源单汇 + 反向建图最短路转换】

传送门
这道题和hdu2680几乎一样.
// 题意: 就是给定一幅有向图(n, k), 有m个人, 给出终点ed. 给出那m个人所在的城市编号和他们行驶速度, 问最小到ed的是哪个编号, 如果时间相等取距离终点远的那个点, 再相等取编号大的那个人.

// 思路: 很明显的反向建图, 以终点做起点跑最短路, 然后扫一遍比较他们的时间和距离就行啦~

注意: 题中说for each case , 所以是多case !!! 我这wa了一发.

AC Code

const int maxm = 5e3 + 5;
int cas=1;
int cnt, head[maxn];
struct node
{
    int to, next, w;
    bool operator < (const node& a) const {
        return w > a.w;
    }
} e[maxm];

void add(int u, int v, int w) {
    e[cnt] = (node){v, head[u], w};
    head[u] = cnt++;
}

void init() {
    cnt = 0;
    memset(head, -1, sizeof(head));
}

bool vis[maxn];
int dis[maxn];
void dij(int st,int ed)
{
    priority_queue q;
    Fill(dis,inf); Fill(vis,0);
    dis[st] = 0;
    q.push((node){st, 0, 0});
    while (!q.empty()) {
        node u = q.top();
        q.pop();
        if(vis[u.to]) continue;
        vis[u.to] = 1;

        for (int i = head[u.to]; ~i; i = e[i].next) {
            node k = e[i];
            if (dis[k.to] > dis[u.to] + k.w) {
                dis[k.to] = dis[u.to] + k.w;
                q.push((node){k.to, 0, dis[k.to]});
            }
        }
    }
}
int p[maxn], v[maxn];
void solve() {
    int n, m, k;
    while(~scanf("%d%d%d", &n, &m, &k)) {
        init();
        for (int i = 1 ; i <= k ; i ++) {
            int u , v, w;
            scanf("%d%d%d", &u, &v, &w);
            add(v, u, w);
        }
        int st; scanf("%d", &st);
        for (int i = 1 ; i <= m ; i ++) {
            scanf("%d", &p[i]);
        }
        for (int i = 1 ; i <= m ; i ++) {
            scanf("%d", &v[i]);
        }
        dij(st, -1);
        db tt = db(inf); int dd = 0, id = -1;
        for (int i = m ; i >= 1 ; i --) {
            if (dis[p[i]] == inf) continue;
            if (tt > 1.0*dis[p[i]]/v[i]) {
                tt = 1.0*dis[p[i]]/v[i];
                dd = dis[p[i]];
                id = i;
            }
            else if (tt == 1.0*dis[p[i]]/v[i] && dis[p[i]] > dd) {
                dd = dis[p[i]];
                id = i;
            }
        }
        if (id == -1) cout << "No one" << endl;
        else cout << id << endl;
    }
}

你可能感兴趣的:(最短路相关)