UVA 11354 Bond (LCA + MST) (堆优化的Prim)

来源:互联网 发布:windows资源管理器黑屏 编辑:程序博客网 时间:2024/05/17 22:18

题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=54643#problem/G


题意:n个点m条无向边相连,每条道路都有一个危险系数,对于q个询问,每个询问都包含一个起点s和终点t的路,使得途径所有边最大危险系数最小


思路:题目要求瓶颈路,但由于需要快速回答询问,所以需要做成易于查询的结构。先求MST,然后改为有根树,并利用类似LCA的办法,通过预处理计算anc和maxcost数组,其中anc[i][j]表示结点i的第2^j级祖先的编号,max[i][j]表示结点i和它的2^j级祖先之间的路径上的最大权值. 预处理后,我们对于每次查询的两个结点p, q,可以先把p和q提升到同一级的位置,让后利用类似二进制展开的方法不断把p和q同时往上“提”,并且更新最大边权


#include <cstdlib>#include <cctype>#include <cstring>#include <cstdio>#include <cmath>#include <algorithm>#include <vector>#include <string>#include <iostream>#include <map>#include <set>#include <queue>#include <stack>#include <bitset>#include <functional>#include <utility>using namespace std;const int maxn = 100010;const int maxm = 200020;const int inf = 0x3f3f3f3f;int n, m;int fa[maxn], cost[maxn], h[maxn];int anc[maxn][20];int mcost[maxn][20];struct edge{    int from, to, w, nxt;    edge() {}    edge(int from, int to, int w) : from(from), to(to), w(w) {}    bool operator < (const edge & rhs) const    {        return w > rhs.w;    }};struct Prim{    int head[maxn], dis[maxn], vis[maxn];    int dep[maxn], pre[maxn], cnt;    int n, sum;    edge e[maxm];    void init(int n)    {        this -> n = n;        cnt = 0;        sum = 0;        memset(head, -1, sizeof(head));    }    void add(int u, int v, int w)    {        e[cnt].from = u;        e[cnt].to = v;        e[cnt].w = w;        e[cnt].nxt = head[u];        head[u] = cnt++;    }    void prim(int s)    {        priority_queue <edge> que;        memset(dis, inf, sizeof(dis));        memset(vis, 0, sizeof(vis));        memset(dep, 0, sizeof(dep));        memset(pre, -1, sizeof(pre));        vis[s] = 1;        dis[s] = 0;        for(int i = head[s]; ~i; i = e[i].nxt)        {            int v = e[i].to;            dis[v] = e[i].w;            que.push(edge(s, v, e[i].w));        }        while(!que.empty())        {            edge now = que.top();            que.pop();            int u = now.to;            if(vis[u])                continue;            vis[u] = 1;            pre[u] = now.from;            dep[u] = dep[now.from] + 1;            dis[u]  = now.w;            sum += now.w;            for(int i = head[u]; ~i; i = e[i].nxt)            {                int v = e[i].to;                int w = e[i].w;                if(!vis[v] && dis[v] > w)                {                    dis[v] = e[i].w;                    que.push(edge(u, v, w));                }            }        }    }} mst;void preprocess(){    for (int i = 1; i <= n; i++)    {        anc[i][0] = fa[i];        mcost[i][0] = cost[i];        for (int j = 1; (1 << j) < n; j++) anc[i][j] = -1;    }    for (int j = 1; (1 << j) < n; j++)    {        for (int i = 1; i <= n; i++)        {            if (anc[i][j - 1] != -1)            {                int a = anc[i][j - 1];                anc[i][j] = anc[a][j - 1];                mcost[i][j] = max(mcost[i][j - 1], mcost[a][j - 1]);            }        }    }}int query(int p, int q){    int log;    if (h[p] < h[q]) swap(p, q);    for (log = 1; (1 << log) <= h[p]; log++);    log--;    int ans = -inf;    for (int i = log; i >= 0; i--)    {        if (h[p] - (1 << i) >= h[q])        {            ans = max(ans, mcost[p][i]);            p = anc[p][i];        }    }    if (p == q) return ans;    for (int i = log; i >= 0; i--)    {        if (anc[p][i] != -1 && anc[p][i] != anc[q][i])        {            ans = max(ans, mcost[p][i]);            p = anc[p][i];            ans = max(ans, mcost[q][i]);            q = anc[q][i];        }    }    ans = max(ans, max(cost[p], cost[q]));    return ans;}int main(){    int ca = 0;    while(~scanf("%d%d", &n, &m))    {        if(ca++)            putchar('\n');        mst.init(n);        for(int i = 0; i < m; i++)        {            int u, v, w;            scanf("%d%d%d", &u, &v, &w);            mst.add(u, v, w);            mst.add(v, u, w);        }        mst.prim(1);//        cout << mst.sum << endl;        for(int i = 1; i <= n; i++)        {            fa[i] = mst.pre[i];            cost[i] = mst.dis[i];            h[i] = mst.dep[i];//            printf("%d %d %d\n", fa[i], cost[i], h[i]);        }        preprocess();        int q;        scanf("%d", &q);        while(q--)        {            int x, y;            scanf("%d%d", &x, &y);            printf("%d\n", query(x, y));        }    }    return 0;}



0 0
原创粉丝点击