zoukankan      html  css  js  c++  java
  • bzoj4152[AMPPZ2014] The Captain

    题意

    给出平面上n个点坐标,点(x1,y1)和点(x2,y2)之间有权值为(min(abs(x1-x2),abs(y1-y2)))的边,求1到n的最短路.

    分析

    老早就知道有这么个题但是一直不会
    也许这就是蒟蒻吧.jpg
    首先我们可以在(x1,y1)和(x2,y2)之间连两条边,权值分别为abs(x1-x2),abs(y1-y2),然后跑最短路,答案显然不变.
    然后我们发现,对从左向右三个点A(x1,y1),B(x2,y2),C(x3,y3),满足x1<=x2<=x3,我们在AB之间连了权值为abs(x1-x2)的边,BC之间连了权值为abs(x2-x3)的边,就不需要在AC之间连权值为abs(x1-x3)的边了.
    于是只需按横坐标排序后相邻的点之间连n-1条双向边,按纵坐标排序后相邻的点之间连n-1条双向边.这个边数就可以跑dijkstra了.
    这个题还有个最小生成树版本:AtCoder Regular Contest 076D Built?

    #include<cstdio>
    #include<queue>
    #include<algorithm>
    using namespace std;
    const int maxn=200005,maxm=1000005;
    struct edge{
      int to,next,w;
    }lst[maxm];int len=1,first[maxn];
    void addedge(int a,int b,int w){
      lst[len].to=b;lst[len].w=w;lst[len].next=first[a];first[a]=len++;
    }
    struct node{
      int v,d;
      node(){}
      node(int _v,int _d){v=_v;d=_d;}
      bool operator <(const node &B)const{
        return d>B.d;
      }
    };
    bool vis[maxn];int dis[maxn];
    int n;
    void dijkstra(){
      for(int i=1;i<=n;++i)dis[i]=0x7f7f7f7f;
      dis[1]=0;
      priority_queue<node> q;
      q.push(node(1,0));
      while(!q.empty()){
        node tmp=q.top();q.pop();
        if(vis[tmp.v])continue;
        vis[tmp.v]=true;
        for(int pt=first[tmp.v];pt;pt=lst[pt].next){
          if(!vis[lst[pt].to]&&dis[lst[pt].to]>tmp.d+lst[pt].w){
    	dis[lst[pt].to]=tmp.d+lst[pt].w;
    	q.push(node(lst[pt].to,tmp.d+lst[pt].w));
          }
        }
      }
    }
    int x[maxn],y[maxn];
    int seq[maxn];
    bool cmpx(const int &a,const int &b){
      return x[a]<x[b];
    }
    bool cmpy(const int &a,const int &b){
      return y[a]<y[b];
    }
    int main(){
      scanf("%d",&n);
      for(int i=1;i<=n;++i)scanf("%d%d",x+i,y+i);
      for(int i=1;i<=n;++i)seq[i]=i;
      sort(seq+1,seq+n+1,cmpx);
      for(int i=1;i<n;++i){
        addedge(seq[i],seq[i+1],x[seq[i+1]]-x[seq[i]]);
        addedge(seq[i+1],seq[i],x[seq[i+1]]-x[seq[i]]);
      }
      sort(seq+1,seq+n+1,cmpy);
      for(int i=1;i<n;++i){
        addedge(seq[i],seq[i+1],y[seq[i+1]]-y[seq[i]]);
        addedge(seq[i+1],seq[i],y[seq[i+1]]-y[seq[i]]);
      }
      dijkstra();
      printf("%d
    ",dis[n]);
      return 0;
    }
    
    
  • 相关阅读:
    【Unity】自定义编辑器窗口——拓展编辑器功能
    【Unity】AssetBundle的使用——打包/解包
    【Unity】使用Resources类管理资源
    【Unity】使用AssetDatabase编辑器资源管理
    【Unity】协程Coroutine及Yield常见用法
    【Unity】制作简易定时器(Timer)
    python3使用csv模块读写csv文件
    Python3使用csv模块csv.writer().writerow()保存csv文件,产生空行的问题
    MongoDB服务无法启动,发生服务特定错误:100
    ValueError: update only works with $ operators
  • 原文地址:https://www.cnblogs.com/liu-runda/p/7103297.html
Copyright © 2011-2022 走看看