m个人随便设定起点= =,所以是有上下界网络流喽、、、
今天刚学,于是试着写了写,1A耶!
费用流是板子哦~
1 /************************************************************** 2 Problem: 2055 3 User: rausen 4 Language: C++ 5 Result: Accepted 6 Time:536 ms 7 Memory:8624 kb 8 ****************************************************************/ 9 10 #include <cstdio> 11 #include <algorithm> 12 13 using namespace std; 14 const int inf = (int) 1e9; 15 const int N = 205; 16 const int M = 500005; 17 18 struct edges{ 19 int next, to, f, cost; 20 edges() {} 21 edges(int _next, int _to, int _f, int _cost) : next(_next), to(_to), f(_f), cost(_cost) {} 22 } e[M]; 23 24 int n, m, tot = 1; 25 int first[N], Del[N], d[N], g[N]; 26 bool v[N]; 27 int q[N], l, r; 28 int S, S1, T; 29 30 inline int read() { 31 int x = 0, sgn = 1; 32 char ch = getchar(); 33 while (ch < '0' || '9' < ch) { 34 if (ch == '-') sgn = -1; 35 ch = getchar(); 36 } 37 while ('0' <= ch && ch <= '9') { 38 x = x * 10 + ch - '0'; 39 ch = getchar(); 40 } 41 return sgn * x; 42 } 43 44 inline void add_edge(int x, int y, int f, int c) { 45 e[++tot] = edges(first[x], y, f, c); 46 first[x] = tot; 47 } 48 49 void Add_Edges(int x, int y, int f, int c) { 50 add_edge(x, y, f, c); 51 add_edge(y, x, 0, -c); 52 } 53 54 inline int calc() { 55 int flow = inf, x; 56 for (x = g[T]; x; x = g[e[x ^ 1].to]) 57 flow = min(flow, e[x].f); 58 for (x = g[T]; x; x = g[e[x ^ 1].to]) 59 e[x].f -= flow, e[x ^ 1].f += flow; 60 return flow; 61 } 62 63 bool spfa() { 64 int x, y; 65 for (x = 1; x <= T; ++x) 66 d[x] = inf; 67 d[S] = 0, v[S] = 1, q[0] = S; 68 for(l = r = 0; l != (r + 1) % N; ++l %= N) { 69 for (x = first[q[l]]; x; x = e[x].next) 70 if (d[q[l]] + e[x].cost < d[y = e[x].to] && e[x].f) { 71 d[y] = d[q[l]] + e[x].cost; 72 g[y] = x; 73 if (!v[y]) 74 q[++r %= N] = y, v[y] = 1; 75 } 76 v[q[l]] = 0; 77 } 78 return d[T] != inf; 79 } 80 81 inline int work() { 82 int res = 0; 83 while (spfa()) 84 res += calc() * d[T]; 85 return res; 86 } 87 88 int main() { 89 int i, j, x; 90 n = read(), m = read(); 91 S = n * 2 + 1, S1 = n * 2 + 2, T = n * 2 + 3; 92 for (i = 1; i <= n; ++i) { 93 x = read(); 94 Add_Edges(i, i + n, 0, 0); 95 Del[i] -= x, Del[i + n] += x; 96 } 97 Add_Edges(S, S1, m, 0); 98 for (i = 1; i <= n; ++i) 99 Add_Edges(S1 ,i, inf, 0); 100 for (i = 1; i <= n; ++i) 101 for (j = i + 1; j <= n; ++j) 102 if ((x = read()) != -1) 103 Add_Edges(i + n, j, inf, x); 104 for (i = 1; i <= n * 2; ++i) 105 if (Del[i] > 0) Add_Edges(S, i, Del[i], 0); 106 else Add_Edges(i, T, -Del[i], 0); 107 printf("%d ", work()); 108 return 0; 109 }