poj 1986

Distance Queries
Time Limit: 2000MS   Memory Limit: 30000K
Total Submissions: 16447   Accepted: 5768
Case Time Limit: 1000MS

Description

Farmer John's cows refused to run in his marathon since he chose a path much too long for their leisurely lifestyle. He therefore wants to find a path of a more reasonable length. The input to this problem consists of the same input as in "Navigation Nightmare",followed by a line containing a single integer K, followed by K "distance queries". Each distance query is a line of input containing two integers, giving the numbers of two farms between which FJ is interested in computing distance (measured in the length of the roads along the path between the two farms). Please answer FJ's distance queries as quickly as possible! 

Input

* Lines 1..1+M: Same format as "Navigation Nightmare" 

* Line 2+M: A single integer, K. 1 <= K <= 10,000 

* Lines 3+M..2+M+K: Each line corresponds to a distance query and contains the indices of two farms. 

Output

* Lines 1..K: For each distance query, output on a single line an integer giving the appropriate distance. 

Sample Input

7 6
1 6 13 E
6 3 9 E
3 5 7 S
4 1 3 N
2 4 20 W
4 7 2 S
3
1 6
1 4
2 6

Sample Output

13
3
36

Hint

Farms 2 and 6 are 20+3+13=36 apart. 

Source

[Submit]   [Go Back]   [Status]   [Discuss]

Home Page   Go Back  To top


All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator

 

 

 1 //求树上任意两点间的距离
 2 //poj    1986
 3 const  int N=45009;
 4 int n,m,cnt,q;
 5 int u,v,w;
 6 int k;
 7 int x,y;
 8 char c[10];
 9 struct Node{
10     int from,to,w,nex;
11 }e[N<<1];
12 struct No{
13     int  to,id;
14 };
15 vector<No>que[N];
16 int dis[N],pre[N],head[N],ans[10009];
17 bool  vis[N];
18 void  init()
19 {
20     for(int i=0;i<N;i++)  head[i]=-1;
21 }
22 void  add(int  u,int v,int w)
23 {
24     e[cnt].from=u;
25     e[cnt].to=v;
26     e[cnt].w=w;
27     e[cnt].nex=head[u];
28     head[u]=cnt++;
29 }
30 int find(int x)
31 {
32     int r,j;
33     r=x;
34     while(r!=pre[r])  r=pre[r];
35     while(x!=r){
36         j=pre[x];
37         pre[x]=r;
38         x=j;
39     }
40     return r;
41 }
42 void dfs(int u,int fa){
43     pre[u]=u;
44     vis[u]=1;
45     for(int i=head[u];i!=-1;i=e[i].nex){
46         int v=e[i].to;
47         if(v==fa)  continue;
48         dis[v]=dis[u]+e[i].w;
49         dfs(v,u);
50     }
51     for(int  i=0;i<que[u].size();i++){
52       No temp=que[u][i];
53       int x=temp.to;
54       if(vis[x]) {
55           int xx=find(x);
56           ans[temp.id]=dis[u]+dis[x]-2*dis[xx];
57       }
58     }
59     pre[u]=fa;
60 }
61 int main()
62 {
63     init();
64     scanf("%d%d",&n,&m);
65     for(int i=1;i<=m;i++)
66     {
67         scanf("%d%d%d%s",&u,&v,&w,&c);
68         add(u,v,w);
69         add(v,u,w);
70     }
71     scanf("%d",&q);
72     for(int i=1;i<=q;i++)
73     {
74         scanf("%d%d",&x,&y);
75         que[x].ph({y,i});
76         que[y].ph({x,i});
77     }
78     dfs(1,0);
79     for(int i=1;i<=q;i++){
80         printf("%d\n",ans[i]);
81     }
82     return  0;
83 }
  •  131072K
 

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×M little squares. That is to say, the height of the rectangle is N and the width of the rectangle is M. 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 QQ 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 NN and MM (1N,M500), giving the number of rows and columns of the maze.

The next N \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,2)(1,2\cdots⋯ (1,M)(1,M) , (2,1)(2,1) , (2,2)(2,2) , \cdots⋯ , (2,M)(2,M) ,⋯ ,(N,M)(N,M).

Each line contains two characters DD and RR and two integers aa , bb (0 \le a,b \le 20000000000a,b2000000000 ), aa is the cost of building the wall between it and its lower adjacent square, and bb 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 00.

The next line contains an integer QQ (1Q100000 ), which represents the number of questions.

The next QQ lines gives four integers, x1y1x2,y2 ( 

 ), which represent two squares and their coordinate are (x1 , y1) and (x2 , y2).

(x,y) means row x and column y.

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 徐州赛区网络预赛

// ACM-ICPC 2018 徐州赛区网络预赛  
//  J. Maze Designer

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
#include <stack>
#include <cstdlib>
#include <iomanip>
#include <cmath>
#include <cassert>
#include <ctime>
#include <map>
#include <set>
#include <vector>
using namespace std;
#define  ull unsigned  long  long 
#define ll  long  long 
#define  ph push_back
/*
把每个square 看成一个点,构成一张图
因为要迷宫的花费最小,那么找最大生成树
再求树上两点间的距离
*/
const  int N=250009;
const  ll mod=1e9+7;
int  n,m,q,cnt;
ll a,b;
char d,r;
int ans[N],pre1[N],pre2[N];
bool vis[N];
int dis[N];
struct  Node{
    int from,to;
    ll w;
    bool operator <(const Node&a)const{
        return w>a.w;//从大到小
    }
}e[N<<1];
struct No{
    int to,id;
};
vector<int>ve[N];
vector<No>que[N];
void  init()
{
    for(int i=0;i<N;i++)  pre1[i]=i;
}
void  add(int u,int v,ll w)
{
    e[cnt].from=u;
    e[cnt].to=v;
    e[cnt].w=w;
    cnt++;
}
int find1(int x)
{
    int  r,j;
    r=x;
    while(r!=pre1[r])  r=pre1[r];
    while(x!=r){
        j=pre1[x];
        pre1[x]=r;
        x=j;
    }
    return r;
}
int find2(int x)
{
    int  r,j;
    r=x;
    while(r!=pre2[r])  r=pre2[r];
    while(x!=r){
        j=pre2[x];
        pre2[x]=r;
        x=j;
    }
    return r;
}
void  prim()
{
    int ret=n*m;
    ll sum=0;
    for(int  i=0;i<cnt;i++)
    {
        if(ret<=1) break;//减少时间
        if(ret>1){
            int  u=find1(e[i].from);
            int v=find1(e[i].to);
            if(u!=v){
                pre1[u]=v;
                ret--;
                sum+=e[i].w;
                ve[e[i].from].ph(e[i].to);
                ve[e[i].to].ph(e[i].from);
            }
        }
    }
}
void dfs(int u,int fa){
    pre2[u]=u;
    vis[u]=1;
    for(int  i=0;i<ve[u].size();i++){
        int v=ve[u][i];
        if(v==fa)  continue;
        dis[v]=dis[u]+1;
        dfs(v,u);
    }
    for(int i=0;i<que[u].size();i++){
        No  temp=que[u][i];
        int x=temp.to;
        if(vis[x]){
            int xx=find2(x);
            //xx  为x,u,的最近公共祖先
            ans[temp.id]=dis[u]+dis[x]-2*dis[xx];
        }
    }
    pre2[u]=fa;
}
int main()
{
    scanf("%d%d",&n,&m);
    init();
    for(int  i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            cin>>d>>a>>r>>b;
            int u=(i-1)*m+j;
            if(i<n)
            {
                int v=i*m+j;
                add(u,v,a);
            }
            if(j<m){
                int  v=(i-1)*m+j+1;
                add(u,v,b);
            }
        }
    }
    sort(e,e+cnt);
    prim();
    scanf("%d",&q);
    int x1,x2,y1,y2;
    for(int  i=1;i<=q;i++)
    {
        scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
        int u=(x1-1)*m+y1;
        int v=(x2-1)*m+y2;
        que[u].ph({v,i});
        que[v].ph({u,i});
    }
    dfs(1,0);
    for(int i=1;i<=q;i++)
    {
        printf("%d\n",ans[i]);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/tingtin/p/9642608.html
今日推荐