因為每一條邊都要走個遍,所以
- 如果一個點的入度等于出度,那么在這個點一定不用走路,
- 如果一個點的入度小于出度,那么肯定還要從其他的點走路到這個點
- 如果一個點的入度大于出度,那么肯定還要從這個店走路到其他的點
現在,我們只要知道每一個點的入度減掉出度,
比如樣例
很顯然,讓
②
②
② 和
①
①
① 一起,
④
④
④ 和
⑤
⑤
⑤ 一起,走路的路程最少
但是如果是這樣
-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;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/165542.html
標籤:其他
下一篇:一個學生關于鴻蒙系統的一些看法
