说好的一天题解来啦!
首先作为usaco的silver题,我被虐了。。。调了两天才搞定
最后发现是sort忘了+1(start + cnt1 (+ 1))还去问管理员要了数据,真是。。。
做法倒不是很难想:
(1)把点分成出度>入度和入度>出度两种
(2)跑一遍网络流
好像会T的很惨。。。然后改进:
发现两条线段交叉一定没有不交叉来得好(就是简单地贪心思想)
于是两类点排序,直接一个一个配对答案一定是最小的。
1 /************************************************************** 2 Problem: 1658 3 User: rausen 4 Language: C++ 5 Result: Accepted 6 Time:32 ms 7 Memory:1040 kb 8 ****************************************************************/ 9 10 #include <cstdio> 11 #include <algorithm> 12 13 using namespace std; 14 15 int n, m, ans, cnt1, cnt2, X, Y; 16 int deg[15000], start[15000], stop[15000], pos[15000]; 17 18 int main(){ 19 scanf("%d%d", &n, &m); 20 for (int i = 1; i <= n; ++i) 21 scanf("%d", pos + i); 22 for (int i = 1; i <= m; ++i){ 23 scanf("%d%d", &X, &Y); 24 ++deg[X], --deg[Y]; 25 } 26 27 for (int i = 1; i <= n; ++i){ 28 for(; deg[i] > 0; --deg[i]) start[++cnt1] = pos[i]; 29 for(; deg[i] < 0; ++deg[i]) stop[++cnt2] = pos[i]; 30 } 31 32 sort(start + 1, start + cnt1 + 1); 33 sort(stop + 1, stop + cnt2 + 1); 34 35 for (int i = 1; i <= cnt1; ++i) 36 ans += abs(start[i] - stop[i]); 37 printf("%d ", ans); 38 return 0; 39 }