1. 程式人生 > >bzoj1658: [Usaco2006 Mar]Water Slides 滑水

bzoj1658: [Usaco2006 Mar]Water Slides 滑水

Description

It's a hot summer day, and Farmer John is letting Betsy go to the water park where she intends to ride every single slide. The water park has N (1 <= N <= 10,000) platforms (numbered 1..N) from which to enter the M (1 <= M <= 10,000) water slides. Each water slide starts at the top of some platform and ends at the bottom of some platform (possibly the same one). Some platforms might have more than one slide; some might not have any. The park is very thin, so the platforms lie along a straight line, each platform at a position Xi (0 <= Xi <= 100,000) meters from one end of the park. One walks from one platform to the next via a sidewalk parallel to the line of platforms.The platforms of the water park are weakly connected; that is, the park cannot be divided into two sets of platforms with no slides running between the two sets. Both the entrance and exit to the park are at platform 1, so Betsy will start and end there. In order to spend more time on the slides, Betsy wants to walk as little as possible. Find the minimum distance Betsy must travel along the ground in order to try every slide in the park exactly once without repeating.

 

    炎熱的夏日裡,約翰帶貝茜去水上樂園滑水.滑水是在一條筆直的人工河裡進行的,沿河設有N(1≤N≤10000)箇中轉站,並開通了M(1≤M≤10000)條滑水路線.路線的起點和終點總在某個中轉站上,起點和終點可能相同.有些中轉站可能是許多條路線的起點或終點,而有些站則可能沒有在任何路線裡被用上.貝茜希望能把所有的路線都滑一遍.    所有中轉站排成一條直線,每個中轉站位於離河的源頭Xi(0≤Xi≤100000)米處.沿著河邊的人行道,貝茜可以從任意位置走到任意一箇中轉站.    中轉站與滑水路線的佈局滿足下述的性質:任意兩個中轉站之間都有滑水路線直接成間接相連.水上樂園的入口與出口都在1號中轉站旁,也就是說,貝茜的滑水路線的起點和終點都是1號中轉站.

    為了更好地享受滑水的快樂,貝茜希望自己花在走路上的時間越少越好.請你幫她計算一下,如果按她的計劃,把所有的路線都不重複地滑一遍,那她至少要走多少路.

 

Input

* Line 1: Two integers, N and M.

* Lines 2..N+1: Line i+1 contains one integer, Xi, the position of platform i. * Lines N+2..M+N+1: Line i+N+1 contains two integers, Si and Di, respectively the start and end platforms of a slide.

    第1行:兩個整數N和M,用空格隔開.

    第2到N+1行:第i+l行包括一個整數Xi,表示i號中轉站距河源頭的距離.

    第N+2到M+N+1行:第i+N+1行包括兩個整數Si和Di,分別表示了一條滑水路線的起點和終點.

 

Output

* Line 1: One integer, the minimum number of meters Betsy must walk.

    輸出一個整數,即貝茜要走的路程長度至少為多少米

Sample Input

5 7
5
3
1
7
10
1 2
1 2
2 3
3 1
4 5
1 5
4 1

Sample Output

8

HINT

 

   貝茜先按1~2~3~1~2路徑滑水.然後走2米,回到1.她再滑行到5,走到4,滑行


到5,走到4,最後滑回1(數字代表中轉站號).


    這樣,她所走的總路程為8米.

 
  一個神奇的思路 我們只關心每個中轉站的 入度和出度之差 顯然,當一個點的入度$-$出度$=a<0$時,我們需要走到這個點$a$次 而當一個點的入度$-$出度$=a>0$時,我們需要這個點向其他點走$a$次 於是我們就 貪心取最近的點。可以用雙指標法方便的實現。
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 using namespace std;
 5 int abs(int a){return a<0?-a:a;}
 6 #define N 100005
 7 int n,m,a[N],id[N],ans;
 8 int main(){
 9     scanf("%d%d",&n,&m);
10     for(int i=1;i<=n;++i) scanf("%d",&id[i]);
11     for(int i=1,q1,q2;i<=m;++i){
12         scanf("%d%d",&q1,&q2);
13         ++a[id[q1]];--a[id[q2]];
14     }
15     for(int l=0,r=0;l<=100000;){//指標指向的是實際座標
16         if(a[l]<=0) ++l;
17         else if(a[r]>=0) ++r;
18         else ans+=abs(l-r),--a[l],++a[r];
19     }printf("%d",ans);
20     return 0;
21 }
View Code