zoukankan      html  css  js  c++  java
  • CodeForces

    ( ext{Description})

    传送门

    ( ext{Solution})

    首先肯定不能直接连边,(m^2) 直接爆炸。

    这种时候,似乎只有想个贪心偷个懒比较靠谱。

    还是和原来一样,只要能证明不更优就行了。考虑点 (x,y) 以横坐标排序中间有一个点 (z),如果用横坐标(x)(y) 需要花费 (x_y-x_x),如果用横坐标(x)(z)(y) 则需要花费 (x_z-x_x+x_y-x_z=x_y-x_x)。与此同时,多增加的 (z) 可以给 ( ext{Yura}) 更多改变用横坐标跳还是纵坐标跳的机会,显然会更优。

    我们将传送点按横坐标排序,再在相邻传送点连一条长度为横坐标之差的边。

    你可能会觉得,如果有这样情况不就好像会错吗?还是一样的 (x,y,z),但是 (z) 纵坐标比 (x,y) 都要大。所以还要将传送点按纵坐标排序,再在相邻传送点连一条长度为纵坐标之差的边。

    其实这里横纵坐标没有什么关联,只是两种路径而已。

    ( ext{Code})

    #include <cstdio>
    
    #define rep(i,_l,_r) for(register signed i=(_l),_end=(_r);i<=_end;++i)
    #define fep(i,_l,_r) for(register signed i=(_l),_end=(_r);i>=_end;--i)
    #define erep(i,u) for(signed i=head[u],v=to[i];i;i=nxt[i],v=to[i])
    #define efep(i,u) for(signed i=Head[u],v=to[i];i;i=nxt[i],v=to[i])
    #define print(x,y) write(x),putchar(y)
    
    template <class T> inline T read(const T sample) {
        T x=0; int f=1; char s;
        while((s=getchar())>'9'||s<'0') if(s=='-') f=-1;
        while(s>='0'&&s<='9') x=(x<<1)+(x<<3)+(s^48),s=getchar();
        return x*f;
    }
    template <class T> inline void write(const T x) {
        if(x<0) return (void) (putchar('-'),write(-x));
        if(x>9) write(x/10);
        putchar(x%10^48);
    }
    template <class T> inline T Max(const T x,const T y) {if(x>y) return x; return y;}
    template <class T> inline T Min(const T x,const T y) {if(x<y) return x; return y;}
    template <class T> inline T fab(const T x) {return x>0?x:-x;}
    template <class T> inline T gcd(const T x,const T y) {return y?gcd(y,x%y):x;}
    template <class T> inline T lcm(const T x,const T y) {return x/gcd(x,y)*y;}
    template <class T> inline T Swap(T &x,T &y) {x^=y^=x^=y;}
    
    #include <map>
    #include <queue>
    #include <cmath>
    #include <vector>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    typedef pair <int,int> Pair;
    
    const int maxn=1e5+5;
    
    map <Pair,int> mp;
    vector <Pair> e[maxn];
    int n,m,cnt=2,dis[maxn];
    bool vis[maxn];
    Pair s,t,p[maxn];
    priority_queue <Pair> q;
    
    bool cmpx(Pair a,Pair b) {
    	return a.first<b.first;
    }
    
    bool cmpy(Pair a,Pair b) {
    	return a.second<b.second;
    }
    
    void Dijkstra() {
    	memset(dis,0x7f,sizeof dis);
    	dis[1]=0;
    	q.push(make_pair(0,1));
    	while(!q.empty()) {
    		Pair tmp=q.top(); q.pop();
    		if(vis[tmp.second]||dis[tmp.second]!=-tmp.first) continue;
    		if(tmp.second==2) return (void)(print(dis[2],'
    '));
    		vis[tmp.second]=1;
    		for(int i=0;i<e[tmp.second].size();++i) {
    			int v=e[tmp.second][i].first,w=e[tmp.second][i].second;
    			if(vis[v]) continue;
    			if(dis[tmp.second]+w<dis[v]) {
    				dis[v]=dis[tmp.second]+w;
    				q.push(make_pair(-dis[v],v));
    			}
    		}
    	}
    }
    
    int main() {
    	n=read(9),m=read(9);
    	s.first=read(9),s.second=read(9),t.first=read(9),t.second=read(9);
    	rep(i,1,m) {
    		p[i].first=read(9),p[i].second=read(9);
    		if(!mp.count(p[i])) mp.insert(make_pair(p[i],++cnt));
    		e[1].push_back(make_pair(mp[p[i]],min(fabs(p[i].first-s.first),fabs(p[i].second-s.second))));
    		e[mp[p[i]]].push_back(make_pair(2,fabs(p[i].first-t.first)+fabs(p[i].second-t.second)));
    	}
    	e[1].push_back(make_pair(2,fabs(s.first-t.first)+fabs(s.second-t.second)));
    	e[2].push_back(make_pair(1,fabs(s.first-t.first)+fabs(s.second-t.second)));
    	sort(p+1,p+m+1,cmpx);
    	rep(i,2,m) e[mp[p[i]]].push_back(make_pair(mp[p[i-1]],p[i].first-p[i-1].first)),e[mp[p[i-1]]].push_back(make_pair(mp[p[i]],p[i].first-p[i-1].first));
    	sort(p+1,p+m+1,cmpy);
    	rep(i,2,m) e[mp[p[i]]].push_back(make_pair(mp[p[i-1]],p[i].second-p[i-1].second)),e[mp[p[i-1]]].push_back(make_pair(mp[p[i]],p[i].second-p[i-1].second));
    	Dijkstra();
    	return 0;
    }
    
  • 相关阅读:
    两个链表的第一个公共结点
    数组中的逆序对
    C++强制类型转换运算符(static_cast、reinterpret_cast、const_cast和dynamic_cast)
    第一个只出现一次的字符
    机器学习算法速览表
    丑数
    设计模式---行为型设计模式【策略模式】
    设计模式---行为型设计模式【备忘录模式】
    设计模式----创建型设计模式【单例模式】
    设计模式----创建型设计模式【简单工厂、工厂方法、抽象工厂】
  • 原文地址:https://www.cnblogs.com/AWhiteWall/p/14086926.html
Copyright © 2011-2022 走看看