[思維題]51 Nod 1671——貨物運輸

題目描述

公元2222年,l國發生了一場戰爭。
小Y負責領導工人運輸物資。
其中有m種物資的運輸方案,每種運輸方案形如li,ri。表示存在一種貨物從li運到ri。
這裏有n個城市,第i個城市與第i+1個城市相連(這裏1號城市和n號城市並不相連),並且從i號城市走到i+1號或者從i+1號走到i號需要耗費1點時間。
由於高科技的存在,小Y想到了一種節省時間的好方案。在X號城市與Y號城市之間設立傳送站,只要這麼做,在X號城市走到Y號城市不需要耗費時間,同樣的,從Y號城市走到X號城市也不需要耗費時間。
但是爲了防止混亂,只能設立這麼一條傳送站。
現在這些運輸方案同時進行,小Y想讓最後到達目的地的運輸方案時間最短。

解題思路

初看這題想到了NOIP某年的某題

這題顯然要二分,考慮怎麼驗證。
先假設s,t 之間有傳送門,對於每個點我們可以列出|xis|+|yit|<=w 這樣的方程。

把所有路徑和傳送門轉看成座標上的點,那麼傳送門可選擇的範圍相對一個點形成一個斜着的正方形。

如果w 可行,顯然這些正方形需要存在交點。

對於這種正方形我們只需要關注兩條斜邊是否相交就可以了。

#include<cstdio>
#include<algorithm>
using namespace std;
char nc(){
    static char buf[100000],*l=buf,*r=buf;
    if (l==r) r=(l=buf)+fread(buf,1,100000,stdin);
    if (l==r) return EOF;return *l++;
}
inline int _read(){
    int num=0;char ch=nc();
    while(ch<'0'||ch>'9') ch=nc();
    while(ch>='0'&&ch<='9') num=num*10+ch-48,ch=nc();
    return  num;
}
const int maxn=500005,INF=2147483647;
struct jz{
    int x,y;
    bool operator<(const jz &b)const{return y-x<b.y-b.x;}
}a[maxn];
int n,m,L,R,mid;
bool check(int x){
    int s1=-INF,s2=-INF,t1=INF,t2=INF;
    for (int i=m;i>=1;i--)
    if (a[i].y-a[i].x>x){
        s1=max(s1,a[i].x+a[i].y-x);
        t1=min(t1,a[i].x+a[i].y+x);
        s2=max(s2,a[i].x-a[i].y-x);
        t2=min(t2,a[i].x-a[i].y+x);
    }else break;
    return s1<=t1&&s2<=t2;
}
int main(){
    freopen("exam.in","r",stdin);
    freopen("exam.out","w",stdout);
    n=_read();m=_read();
    for (int i=1;i<=m;i++){a[i].x=_read(),a[i].y=_read();if (a[i].x>a[i].y) swap(a[i].x,a[i].y);}
    sort(a+1,a+m+1);
    int L=0,R=a[m].y-a[m].x;
    while(L<=R){
        mid=L+(R-L>>1);
        if (check(mid)) R=mid-1;else L=mid+1;
    }
    printf("%d\n",L);
    return 0;
}
發佈了157 篇原創文章 · 獲贊 61 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章