因為每一條邊都要走個遍,所以
現在,我們只要知道每一個點的入度減掉出度。
比如樣例
很顯然,讓
②
②
② 和
①
①
① 一起,
④
④
④ 和
⑤
⑤
⑤ 一起,走路的路程最少
但是如果是這樣
-1 2 -1 3 1 -2 -2
不能剛好兩個匹配的話
顯然,一個負數一定是和最近的一個正數,一個正數一定是和最近的一個負數,那麼,怎麼找最近的一個正數(負數)呢?
第一:暴力每次 O ( n ) O(n) O(n) 找
因為這個方法有過多的重複查詢(當然,你也可以預處理出來)
我們其實可以每次直接搞,不管他的右邊是不是和他符號相反的數。
-1 2 -1 3 1 -2 -2
0 1 -1 3 1 -2 -2
0 0 0 3 1 -2 -2
0 0 0 0 4 -2 -2
0 0 0 0 0 2 -2
0 0 0 0 0 0 0
很顯然,這個方法也是對的。
其實就很像發試卷,如果試卷總數是對的,那麼老師只要隨便的分給每個組,第一個組多了或少了就到第二個組那裡調整,第二個組到第三個組那裡調整,……指導最後一個組一定是剛剛好的。
#include<cstdio>
#include<algorithm>
using namespace std;
struct zj{
int a,d;
bool operator < (const zj &x)const{
return a<x.a;
}
}a[10001];
int n,m,x,y;
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)scanf("%d",&a[i].a);
for(int i=1;i<=m;i++){
scanf("%d%d",&x,&y);
a[x].d++;
a[y].d--;
}
sort(a+1,a+1+n);//按照距離排序
int ans=0;
for(int i=1;i<n;i++){
ans+=abs(a[i].d)*(a[i+1].a-a[i].a);//要走的路程
a[i+1].d+=a[i].d;//調整試卷操作
}
printf("%d",ans);
return 0;
}