首页 > 代码库 > 2015山东信息学夏令营 Day5T3 路径

2015山东信息学夏令营 Day5T3 路径

问题描述:

给定平面上的n个点,定义(x1,y1)到(x2,y2)的费用为min(|x1-x2|,|y1-y2|),求从1号点走到n号点的最小费用。

输入:

第一行包含一个正整数n,表示点数。

接下来n行,每行包含两个整数x[i],y[i](0<=x[i],y[i]<=10^9),依次表示每个点的坐标。

 

输出:

一个整数,即最小费用。

输入输出样例:

path.in

path.out

5
2 2
1 1
4 5
7 1
6 7

2

 

 

 

数据范围:

对于30%的数据,1<=n<=100;

对于60%的数据,1<=n<=1000;

对于全部的数据,1<=n<=200000;

 

思路:

1、60分直接最短路

2、对于坐标系中连续的三个点,(x1,y1),(x2,y2),(x3,y3),总有min(x2-x1,y2-y1) + min(x3-x2,y3-y2) ≤ min(x3 -  x1,y3 - y1),所以在建图的时候,可以按x,y分别排一遍序,然后,相邻的点建边,这样边数为2*n,再用堆dij就可以了

代码:

#include<iostream>#include<cstdio>#include<string>#include<cstring>#include<algorithm>#include<vector>#include<queue>#define maxn 200005#define inf ~0U>>1using namespace std;struct point{    int x;    int y;    int pos;};struct orz{    int p;    int d;    friend bool operator < (orz a,orz b){        return a.d > b.d;    }};struct edge{    int v;    int w;};priority_queue< orz > ss;vector<edge> g[maxn];point pt[maxn];int flag = 0,v[maxn],d[maxn],n;bool cmpa(point a,point b){    return a.x < b.x;}bool cmpb(point a,point b){    return a.y < b.y;}void init(){    cin>>n;    int tx,ty;    for(int i = 1;i <= n;i++){        scanf("%d%d",&tx,&ty);        pt[i].x = tx;        pt[i].y = ty;        pt[i].pos = i;    }    for(int i = 1;i <= n;i++) d[i] = inf;    sort(pt+1,pt+1+n,cmpa);    edge tmp;    for(int i = 1;i < n;i++){        tmp.w = pt[i+1].x - pt[i].x;        tmp.v = pt[i + 1].pos;        g[pt[i].pos].push_back(tmp);        tmp.v = pt[i].pos;        g[pt[i+1].pos].push_back(tmp);    }    sort(pt+1,pt+1+n,cmpb);    for(int i = 1;i < n;i++){        tmp.w = pt[i+1].y - pt[i].y;        tmp.v = pt[i + 1].pos;        g[pt[i].pos].push_back(tmp);        tmp.v = pt[i].pos;        g[pt[i+1].pos].push_back(tmp);    }}void dij(){    orz tmp;    d[1] = 0;    tmp.p = 1;    tmp.d = 0;    ss.push(tmp);    flag++;    int to,wei,x,dd;    edge j;    while(!ss.empty()){        tmp = ss.top();        ss.pop();        x = tmp.p;        dd = tmp.d;        if(v[x] == flag) continue;        v[x] = flag;        for(int i = 0;i < g[x].size();i++){            j = g[x][i];            to = j.v;            wei = j.w;            if(d[to] > dd + wei){                d[to] = dd + wei;                tmp.d = dd + wei;                tmp.p = to;                ss.push(tmp);            }        }    }    cout<<d[n];}int main(){    init();    dij();    return 0;}

 

2015山东信息学夏令营 Day5T3 路径