bzoj4152 The Captain (dijkstra)

做dijkstra,但只需要贪心地把每个点连到它左边、右边、上边、下面的第一个点就可以了

 1 #include<bits/stdc++.h>
 2 #define pa pair<int,int>
 3 #define lowb(x) ((x)&(-(x)))
 4 #define REP(i,n0,n) for(i=n0;i<=n;i++)
 5 #define PER(i,n0,n) for(i=n;i>=n0;i--)
 6 #define MAX(a,b) ((a>b)?a:b)
 7 #define MIN(a,b) ((a<b)?a:b)
 8 #define CLR(a,x) memset(a,x,sizeof(a))
 9 #define rei register int
10 using namespace std;
11 typedef long long ll;
12 const int maxn=2e5+10;
13
14 inline ll rd(){
15     ll x=0;char c=getchar();int neg=1;
16     while(c<‘0‘||c>‘9‘){if(c==‘-‘) neg=-1;c=getchar();}
17     while(c>=‘0‘&&c<=‘9‘) x=x*10+c-‘0‘,c=getchar();
18     return x*neg;
19 }
20
21 struct Node{
22     int x,y,id;
23 }pos[maxn];
24 int N,xnxt[maxn][2],ynxt[maxn][2];
25 int dis[maxn],px[maxn],py[maxn];
26 bool flag[maxn];
27 priority_queue<pa,vector<pa>,greater<pa> > q;
28
29 inline bool cmp1(Node a,Node b){return a.x<b.x;}
30 inline bool cmp2(Node a,Node b){return a.y<b.y;}
31
32 inline void psh(int x,int d){
33     if(dis[x]==-1||d<dis[x]){
34         dis[x]=d;
35         if(!flag[x]) q.push(make_pair(d,x));
36     }
37 }
38
39 inline void dijkstra(){
40     memset(dis,-1,sizeof(dis));dis[1]=0;
41     q.push(make_pair(0,1));
42     while(!q.empty()){
43         int p=q.top().second;q.pop();if(flag[p]) continue;
44         flag[p]=1;
45         if(p==N) return;
46         if(xnxt[p][0]) psh(xnxt[p][0],dis[p]+px[p]-px[xnxt[p][0]]);
47         if(xnxt[p][1]) psh(xnxt[p][1],dis[p]-px[p]+px[xnxt[p][1]]);
48         if(ynxt[p][0]) psh(ynxt[p][0],dis[p]+py[p]-py[ynxt[p][0]]);
49         if(ynxt[p][1]) psh(ynxt[p][1],dis[p]-py[p]+py[ynxt[p][1]]);
50     }
51 }
52
53 int main(){
54     //freopen(".in","r",stdin);
55     rei i,j,k;
56     N=rd();
57     for(i=1;i<=N;i++) px[i]=pos[i].x=rd(),py[i]=pos[i].y=rd(),pos[i].id=i;
58     sort(pos+1,pos+N+1,cmp1);
59     for(i=1;i<=N;i++){
60         xnxt[pos[i].id][0]=pos[i-1].id;
61         xnxt[pos[i].id][1]=pos[i+1].id;
62     }
63     sort(pos+1,pos+N+1,cmp2);
64     for(i=1;i<=N;i++){
65         ynxt[pos[i].id][0]=pos[i-1].id;
66         ynxt[pos[i].id][1]=pos[i+1].id;
67     }
68     dijkstra();
69     printf("%d\n",dis[N]);
70     return 0;
71 }

原文地址:https://www.cnblogs.com/Ressed/p/9735545.html

时间: 2024-11-06 03:35:34

bzoj4152 The Captain (dijkstra)的相关文章

BZOJ4152The Captain[DIjkstra]

4152: [AMPPZ2014]The Captain Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 700  Solved: 266[Submit][Status][Discuss] Description 给定平面上的n个点,定义(x1,y1)到(x2,y2)的费用为min(|x1-x2|,|y1-y2|),求从1号点走到n号点的最小费用. Input 第一行包含一个正整数n(2<=n<=200000),表示点数. 接下来n行,每行包含两

bzoj4152 The Captain

Description 给定平面上的n个点,定义(x1,y1)到(x2,y2)的费用为min(|x1-x2|,|y1-y2|),求从1号点走到n号点的最小费用. Input 第一行包含一个正整数n(2<=n<=200000),表示点数. 接下来n行,每行包含两个整数x[i],y[i](0<=x[i],y[i]<=10^9),依次表示每个点的坐标. Output 一个整数,即最小费用. Sample Input 5 2 2 1 1 4 5 7 1 6 7 Sample Output

循环队列+堆优化dijkstra最短路 BZOJ 4152: [AMPPZ2014]The Captain

循环队列基础知识 1.循环队列需要几个参数来确定 循环队列需要2个参数,front和rear 2.循环队列各个参数的含义 (1)队列初始化时,front和rear值都为零: (2)当队列不为空时,front指向队列的第一个元素,rear指向队列最后一个元素的下一个位置: (3)当队列为空时,front与rear的值相等,但不一定为零: 3.循环队列入队的伪算法 (1)把值存在rear所在的位置: (2)rear=(rear+1)%maxsize ,其中maxsize代表数组的长度: 4.循环队列

bzoj4152[AMPPZ2014]The Captain 最短路

4152: [AMPPZ2014]The Captain Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 1517  Solved: 603[Submit][Status][Discuss] Description 给定平面上的n个点,定义(x1,y1)到(x2,y2)的费用为min(|x1-x2|,|y1-y2|),求从1号点走到n号点的最小费用. Input 第一行包含一个正整数n(2<=n<=200000),表示点数. 接下来n行,每行包含

BZOJ4152: [AMPPZ2014]The Captain

Description 给定平面上的n个点,定义(x1,y1)到(x2,y2)的费用为min(|x1-x2|,|y1-y2|),求从1号点走到n号点的最小费用. Input 第一行包含一个正整数n(2<=n<=200000),表示点数. 接下来n行,每行包含两个整数x[i],y[i](0<=x[i],y[i]<=10^9),依次表示每个点的坐标. Output 一个整数,即最小费用. Sample Input 5 2 2 1 1 4 5 7 1 6 7 Sample Output

【BZOJ】【4152】【AMPZZ2014】The Captain

最短路 题解:http://zyfzyf.is-programmer.com/posts/97953.html 按x坐标排序,相邻点之间连边.满足dist(x1,x3)<=dist(x1,x2)+dist(x2,x3)(因为可以走y) 再按y坐标排序,相邻点之间连边.同上 然而SPFA挂了……写了Dijkstra 1 /************************************************************** 2 Problem: 4152 3 User: Tu

BZOJ 4152: [AMPPZ2014]The Captain( 最短路 )

先按x排序, 然后只有相邻节点的边才有用, 我们连起来, 再按y排序做相同操作...然后就dijkstra ------------------------------------------------------------------------ #include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<queue> #include

bzoj4152

忘记优先队列初始是大根堆了.... 调了半天... 1 #include<cstdio> 2 #include<cstring> 3 #include<cmath> 4 #include<ctime> 5 #include<cstdlib> 6 #include<iostream> 7 #include<algorithm> 8 #include<queue> 9 #include<vector>

图论---The Captain

B-The Captain 给定平面上的n个点,定义(x1,y1)到(x2,y2)的费用为min(|x1-x2|,|y1-y2|),求从1号点走到n号点的最小费用. Input 第一行包含一个正整数n(2<=n<=200000),表示点数. 接下来n行,每行包含两个整数x[i],yi,依次表示每个点的坐标. Output 一个整数,即最小费用. Sample Input 5 2 2 1 1 4 5 7 1 6 7 Sample Output 2 #include<cstdio> #