poj 1986
Distance Queries
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]
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 }
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 (1≤N,M≤500), 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 20000000000≤a,b≤2000000000 ), 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 (1≤Q≤100000 ), which represents the number of questions.
The next QQ lines gives four integers, x1, y1, x2,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 徐州赛区网络预赛 // 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; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现