首页 > 代码库 > BZOJ2597 [Wc2007]剪刀石头布
BZOJ2597 [Wc2007]剪刀石头布
什么鬼。。。冬令营题目不看题解能做?
(看了题解也不会2333)
其中有一部还是可以仔细思考一下的,就是对于费用流,如果每条边边满足:cost = a * flow2,如何做?
我们可以拆边,新边上,每条边流量为1,费用为a * (x2 - (x - 1)2)(就是费用为a * (12 - 02), a * (22 - 12)...)
拆边的思想还是很广泛的,恩...!
1 /************************************************************** 2 Problem: 2597 3 User: rausen 4 Language: C++ 5 Result: Accepted 6 Time:11144 ms 7 Memory:10756 kb 8 ****************************************************************/ 9 10 #include <cstdio> 11 #include <cstring> 12 #include <algorithm> 13 14 using namespace std; 15 const int Num = 105; 16 const int N = Num * Num; 17 const int M = 500005; 18 const int inf = (int) 1e9; 19 20 struct edges { 21 int next, to, f, cost; 22 edges() {} 23 edges(int _n, int _t, int _f, int _c) : next(_n), to(_t), f(_f), cost(_c) {} 24 } e[M]; 25 26 int tot = 1, first[N]; 27 int n, m, S, T; 28 int in[Num], d[N], q[N], g[N]; 29 int sum[M]; 30 bool v[N]; 31 32 inline int read() { 33 int x = 0; 34 char ch = getchar(); 35 while (ch < ‘0‘ || ‘9‘ < ch) 36 ch = getchar(); 37 while (‘0‘ <= ch && ch <= ‘9‘) { 38 x = x * 10 + ch - ‘0‘; 39 ch = getchar(); 40 } 41 return x; 42 } 43 44 inline void Add_Edges(int x, int y, int f, int c) { 45 e[++tot] = edges(first[x], y, f, c), first[x] = tot; 46 e[++tot] = edges(first[y], x, 0, -c), first[y] = tot; 47 } 48 49 inline int calc() { 50 int flow = inf, x; 51 for (x = g[T]; x; x = g[e[x ^ 1].to]) 52 flow = min(flow, e[x].f); 53 for (x = g[T]; x; x = g[e[x ^ 1].to]) 54 e[x].f -= flow, e[x ^ 1].f += flow; 55 return flow; 56 } 57 58 bool spfa() { 59 int x, y, l, r; 60 for (x = 1; x <= T; ++x) 61 d[x] = inf; 62 d[S] = 0, v[S] = 1, q[0] = S; 63 for(l = r = 0; l != (r + 1) % N; ++l %= N) { 64 for (x = first[q[l]]; x; x = e[x].next) 65 if (d[q[l]] + e[x].cost < d[y = e[x].to] && e[x].f) { 66 d[y] = d[q[l]] + e[x].cost, g[y] = x; 67 if (!v[y]) 68 q[++r %= N] = y, v[y] = 1; 69 } 70 v[q[l]] = 0; 71 } 72 return d[T] != inf; 73 } 74 75 inline int work() { 76 int res = 0; 77 while (spfa()) 78 res += calc() * d[T]; 79 return res; 80 } 81 82 void build_graph() { 83 int i, j, x, now = 0; 84 for (i = 1; i <= n; ++i) 85 for (j = 1; j <= n; ++j) { 86 x = read(); 87 if (j <= i) continue; 88 sum[++now] = i + j; 89 if (x == 2) { 90 Add_Edges(now, i + m, 1, 0), Add_Edges(now, j + m, 1, 0); 91 ++in[i], ++in[j]; 92 } else 93 if (x == 1) Add_Edges(now, i + m, 1, 0), ++in[i]; 94 else Add_Edges(now, j + m, 1, 0), ++in[j]; 95 } 96 for (i = 1; i <= m; ++i) 97 Add_Edges(S, i, 1, 0); 98 for (i = 1; i <= n; ++i) 99 for (j = 1; j <= in[i]; ++j)100 Add_Edges(i + m, T, 1, 2 * j - 1);101 }102 103 void make_ans() {104 int a[Num][Num], i, j, x;105 memset(a, 0, sizeof(a));106 for (i = 1; i <= m; ++i)107 for (x = first[i]; x; x = e[x].next)108 if (!e[x].f) a[e[x].to - m][sum[i] - e[x].to + m] = 1;109 for (i = 1; i <= n; ++i) {110 for (j = 1; j <= n; ++j)111 printf("%d ", a[i][j]);112 printf("\n");113 }114 }115 116 int main() {117 n = read(), m = n * (n - 1) / 2;118 S = n + m + 1, T = S + 1;119 build_graph();120 printf("%d\n", (n * (n - 1) * (n - 2) / 3 + m - work()) / 2);121 make_ans();122 return 0;123 }
(p.s. 为何这么慢= =我去。。)
BZOJ2597 [Wc2007]剪刀石头布
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。