ACM-ICPC 2018 徐州賽區網絡預賽 J. Maze Designer(最大生成樹+LCA)

After the long vacation, the maze designer master has to do his job. A tour company gives him a map which is a rectangle. The map consists of N×MN \times MN×M little squares. That is to say, the height of the rectangle is NNN and the width of the rectangle is MMM. The master knows exactly how the maze is going to use. The tour company will put a couple in two different squares in the maze and make them seek each other. Of course,the master will not make them find each other easily. The only thing the master does is building some wall between some little squares. He knows in that way, wherever the couple is put, there is only one path between them. It is not a difficult thing for him, but he is a considerate man. He also knows that the cost of building every wall between two adjacent squares is different(Nobody knows the reason). As a result, he designs the maze to make the tour company spend the least money to build it.

Now, here's your part. The tour company knows you're the apprentice of the master, so they give you a task. you're given QQQ qustions which contain the information of where the couple will be put. You need to figure out the length of the shortest path between them.

However,the master doesn't tell you how he designs the maze, but he believes that you, the best student of himself, know the way. So he goes on vacation again.

Input

The first line of the input contains two integers NNN and MMM (1≤N,M≤5001 \le N,M \le 5001≤N,M≤500), giving the number of rows and columns of the maze.

The next N×MN \times MN×M lines of the input give the information of every little square in the maze, and their coordinates are in order of (1,1)(1,1)(1,1) , (1,2)(1,2)(1,2) ⋯\cdots⋯ (1,M)(1,M)(1,M) , (2,1)(2,1)(2,1) , (2,2)(2,2)(2,2) , ⋯\cdots⋯ , (2,M)(2,M)(2,M) , ⋯\cdots⋯ ,(N,M)(N,M)(N,M).

Each line contains two characters DDD and RRR and two integers aaa , bbb (0≤a,b≤20000000000 \le a,b \le 20000000000≤a,b≤2000000000 ), aaa is the cost of building the wall between it and its lower adjacent square, and bbb is the cost of building the wall between it and its right adjacent square. If the side is boundary, the lacking path will be replaced with X 000.

The next line contains an integer QQQ (1≤Q≤1000001 \le Q \le 1000001≤Q≤100000 ), which represents the number of questions.

The next QQQ lines gives four integers, x1x_1x1​, y1y_1y1​, x2x_2x2​, y2y_2y2​ ( 1≤x11 \le x_11≤x1​ , x2≤Nx_2 \le Nx2​≤N , 1≤y11 \le y_11≤y1​ , y2≤My_2 \le My2​≤M ), which represent two squares and their coordinate are (x1x_1x1​ , y1y_1y1​) and (x2x_2x2​ , y2y_2y2​).

(xxx,yyy) means row xxx and column yyy.

It is guaranteed that there is only one kind of maze.

Output

For each question, output one line with one integer which represents the length of the shortest path between two given squares.

樣例輸入

3 3
D 1 R 9
D 7 R 8
D 4 X 0
D 2 R 6
D 12 R 5
D 3 X 0
X 0 R 10
X 0 R 11
X 0 X 0
3
1 1 3 3
1 2 3 2
2 2 3 1

樣例輸出

4
2
2

題目來源

ACM-ICPC 2018 徐州賽區網絡預賽

話說這道題並不難,讀懂題意是關鍵,根據題目數據構成一張圖,給出兩點,如果兩點有唯一路徑的話,肯定是一棵樹,所以得構造一棵樹,因爲要求花費最小,所以要求圖的最大生成樹,兩點之間的距離用LCA求一下就行了

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 500000;
int pre[MAXN];
int Find(int x)
{
    if(x == pre[x]) return x;
    else return pre[x] = Find(pre[x]);
}
bool join(int x,int y)
{
    int fx = Find(x);
    int fy = Find(y);
    if(fx != fy) {
        pre[fy] = fx;
        return true;
    }
    return false;
}
struct node
{
    int u,v,w;
}e1[MAXN];
bool cmp(struct node a,struct node b)
{
    return a.w > b.w;
}
/*****************************************/
int rmq[2 * MAXN];
struct ST
{
    int mm[2 * MAXN];
    int dp[2 * MAXN][20];
    void init(int n)
    {
        mm[0] = -1;
        for(int i = 1; i <= n; i++) {
            mm[i] = ((i & (i - 1)) == 0) ? mm[i - 1] + 1 : mm[i - 1];
            dp[i][0] = i;
        }
        for(int j = 1; j <= mm[n]; j++) {
            for(int i = 1; i + (1 << j) - 1 <= n; i++) {
                dp[i][j] = rmq[dp[i][j - 1]] < rmq[dp[i + (1 << (j - 1))][j
                - 1]] ? dp[i][j - 1] : dp[i + (1 << (j - 1))][j - 1];
            }
        }
    }
    int query(int a,int b)
    {
        if(a > b) swap(a,b);
        int k = mm[b - a + 1];
        return rmq[dp[a][k]] <= rmq[dp[b - (1 << k) + 1][k]] ? dp[a][k] :
            dp[b - (1 << k) + 1][k];
    }
};
struct Edge
{
    int to,Next;
};
Edge edge[MAXN * 2];
int tot,head[MAXN];
int F[MAXN * 2];
int P[MAXN];
int dis[MAXN];
int cnt;
ST st;
void init()
{
    tot = 0;
    memset(head,-1,sizeof(head));
}
void addedge(int u,int v)
{
    edge[tot].to = v;
    edge[tot].Next = head[u];
    head[u] = tot++;
}
void dfs(int u,int pre,int dep)
{
    F[++cnt] = u;
    rmq[cnt] = dep;
    P[u] = cnt;
    for(int i = head[u]; i != -1; i = edge[i].Next) {
        int v = edge[i].to;
        if(v == pre) continue;
        dis[v] = dis[u] + 1;
        dfs(v,u,dep + 1);
        F[++cnt] = u;
        rmq[cnt] = dep;
    }
}
void LCA_init(int root,int node_num)
{
    cnt = 0;
    dfs(root,root,0);
    st.init(2 * node_num - 1);
}
int query_lca(int u,int v)
{
    return F[st.query(P[u],P[v])];
}
/*****************************************/
int main(void)
{
    int n,m,w1,w2;
    int x1,x2,y1,y2,x,y;
    char c1[2],c2[2];
    scanf("%d %d",&n,&m);
    int cnt = 0,cnt1 = 0;
    for(int i = 1; i <= n * m; i++) {
        pre[i] = i;
        scanf("%s %d %s %d",c1,&w1,c2,&w2);
        if(c1[0] == 'D') e1[cnt].u = i,e1[cnt].v = i + m,e1[cnt++].w = w1;
        if(c2[0] == 'R') e1[cnt].u = i,e1[cnt].v = i + 1,e1[cnt++].w = w2;
    }
    sort(e1,e1 + cnt,cmp);
    int cost = 0;
    init();
    for(int i = 0; i < cnt; i++) {
        if(join(e1[i].u,e1[i].v)) {
            cnt1++;cost += e1[i].w;
            addedge(e1[i].u,e1[i].v);
            addedge(e1[i].v,e1[i].u);
        }
    }
    LCA_init(1,n * m);
    int q;
    scanf("%d",&q);
    while(q--) {
        scanf("%d %d %d %d",&x1,&y1,&x2,&y2);
        x = (x1 - 1) * m + y1;
        y = (x2 - 1) * m + y2;
        printf("%d\n",dis[x] + dis[y] - 2 * dis[query_lca(x,y)]);
    }
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章