[LP对偶][含正权环的最大费用流] SRM 676 div1 1000pts Farmville
来源:互联网 发布:js图片轮播思路 编辑:程序博客网 时间:2024/05/22 12:48
Solution
LP对偶:
建立源点和汇点。这道题的话有这样的一些限值。
把
去正权环后跑最小费用最大流。
// BEGIN CUT HERE// END CUT HERE#line 5 "Farmville.cpp"#include <bits/stdc++.h>using namespace std;typedef long long ll;const ll N = 111;const ll INF = 1 << 30;const ll INFll = 1ll << 58;struct edge { int to, next, cap, cost; edge(int t = 0, int n = 0, int co = 0, int ca = 0):to(t), next(n), cost(co), cap(ca) {}};edge G[N * N * 2];int head[N];ll dis[N];int vis[N], pre[N];int t[N], c[N];int mp[N][N];int Gcnt, S, T;ll W0;int n, bud, ans, smt;queue<int> Q;class Farmville {public: inline int x(int i) { return i << 1; } inline int y(int i) { return i << 1 | 1; } inline bool SPFA(int S, int T) { for (int i = 0; i <= y(n + 3); i++) dis[i] = -INFll; Q.push(S); vis[S] = true; dis[S] = 0; while (!Q.empty()) { ll x = Q.front(); Q.pop(); vis[x] = false; for (int i = head[x]; i; i = G[i].next) { edge &e = G[i]; if (e.cap && e.cost + dis[x] > dis[e.to]) { dis[e.to] = e.cost + dis[x]; pre[e.to] = i ^ 1; if (!vis[e.to]) { Q.push(e.to); vis[e.to] = true; } } } } return dis[T] != -INFll; } inline ll MCMF(int S, int T) { ll cost = 0; int f; while (SPFA(S, T)) { f = INF; for (int u = T; u != S; u = G[pre[u]].to) f = min(f, G[pre[u] ^ 1].cap); cost += f * dis[T]; for (int u = T; u != S; u = G[pre[u]].to) { G[pre[u] ^ 1].cap -= f; G[pre[u]].cap += f; } } return cost; } inline void Add(int from, int to, int cost, int cap) {// printf("%d %d %d %d\n", from, to, cost, cap); G[++Gcnt] = edge(to, head[from], cost, cap); head[from] = Gcnt;// printf("%d %d %d %d\n", to, from, -cost, 0); G[++Gcnt] = edge(from, head[to], -cost, 0); head[to] = Gcnt; } inline void AddEdge(int from, int to, int cost, int cap) { if (cost > 0) { Add(S, to, 0, cap); Add(from, T, 0, cap); Add(to, from, -cost, cap); W0 += (ll)cost * cap; } else Add(from, to, cost, cap); } inline bool Check(int ti) { memset(head, 0, sizeof head); W0 = 0; Gcnt = 1; smt = 0; ll s = x(n + 1), t = y(n + 1); S = x(n + 2); T = y(n + 2); for (int i = 1; i <= n; i++) { AddEdge(s, x(i), 0, INF); AddEdge(y(i), t, 0, INF); } AddEdge(t, s, -ti, INF); for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) if (i != j && mp[j][i]) AddEdge(y(i), x(j), 0, INF); for (int i = 1; i <= n; i++) { AddEdge(x(i), y(i), ::t[i], c[i]); AddEdge(x(i), y(i), 0, INF); } W0 += MCMF(S, T); return W0 <= bud; } int minTime(vector <string> s, vector <int> time, vector <int> cost, int budget) { bud = budget; n = time.size(); smt = 0; for (int i = 1; i <= n; i++) { t[i] = time[i - 1]; c[i] = cost[i - 1]; for (int j = 1; j <= n; j++) mp[i][j] = s[i - 1][j - 1] - '0'; smt += t[i]; } int L = 0, R = smt, Mid; while (L <= R) { Mid = (L + R) >> 1; if (Check(Mid)) R = (ans = Mid) - 1; else L = Mid + 1; } return ans; }// BEGIN CUT HERE public: void run_test(int Case) { if ((Case == -1) || (Case == 0)) test_case_0(); if ((Case == -1) || (Case == 1)) test_case_1(); if ((Case == -1) || (Case == 2)) test_case_2(); if ((Case == -1) || (Case == 3)) test_case_3(); if ((Case == -1) || (Case == 4)) test_case_4(); if ((Case == -1) || (Case == 5)) test_case_5(); } private: template <typename T> string print_array(const vector<T> &V) { ostringstream os; os << "{ "; for (typename vector<T>::const_iterator iter = V.begin(); iter != V.end(); ++iter) os << '\"' << *iter << "\","; os << " }"; return os.str(); } void verify_case(int Case, const int &Expected, const int &Received) { cerr << "Test Case #" << Case << "..."; if (Expected == Received) cerr << "PASSED" << endl; else { cerr << "FAILED" << endl; cerr << "\tExpected: \"" << Expected << '\"' << endl; cerr << "\tReceived: \"" << Received << '\"' << endl; } } void test_case_0() { string Arr0[] = {"000", "000", "000"}; vector <string> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arr1[] = {25,15,10}; vector <int> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); int Arr2[] = {1,2,3}; vector <int> Arg2(Arr2, Arr2 + (sizeof(Arr2) / sizeof(Arr2[0]))); int Arg3 = 50; int Arg4 = 6; verify_case(0, Arg4, minTime(Arg0, Arg1, Arg2, Arg3)); } void test_case_1() { string Arr0[] = {"0000", "1000", "0100", "0010"}; vector <string> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arr1[] = {25,25,25,25}; vector <int> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); int Arr2[] = {100,200,300,400}; vector <int> Arg2(Arr2, Arr2 + (sizeof(Arr2) / sizeof(Arr2[0]))); int Arg3 = 2800; int Arg4 = 74; verify_case(1, Arg4, minTime(Arg0, Arg1, Arg2, Arg3)); } void test_case_2() { string Arr0[] = {"01110", "00010", "00000", "00000", "10000"}; vector <string> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arr1[] = {25,10,23,12,5}; vector <int> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); int Arr2[] = {123,456,789,1011,1213}; vector <int> Arg2(Arr2, Arr2 + (sizeof(Arr2) / sizeof(Arr2[0]))); int Arg3 = 1000000000; int Arg4 = 0; verify_case(2, Arg4, minTime(Arg0, Arg1, Arg2, Arg3)); } void test_case_3() { string Arr0[] = {"00", "00"}; vector <string> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arr1[] = {25,25}; vector <int> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); int Arr2[] = {1000000000,1000000000} ; vector <int> Arg2(Arr2, Arr2 + (sizeof(Arr2) / sizeof(Arr2[0]))); int Arg3 = 1000000000; int Arg4 = 25; verify_case(3, Arg4, minTime(Arg0, Arg1, Arg2, Arg3)); } void test_case_4() { string Arr0[] = {"0000000000000000", "1000000000000000", "1000000000000000", "0100000000000000", "0110000000000000", "0010000000000000", "0001000000000000", "0001100000000000", "0000110000000000", "0000010000000000", "0000001100000000", "0000000110000000", "0000000011000000", "0000000000110000", "0000000000011000", "0000000000000110"}; vector <string> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arr1[] = {24,25,23,25,23,24,25,24,23,22,25,24,23,25,23,25}; vector <int> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); int Arr2[] = {82912,129482,235934,3294812,523942,460492,349281,592384,109248,2305923,340945,2304934,582396,548935,767872,423981}; vector <int> Arg2(Arr2, Arr2 + (sizeof(Arr2) / sizeof(Arr2[0]))); int Arg3 = 87654321; int Arg4 = 49; verify_case(4, Arg4, minTime(Arg0, Arg1, Arg2, Arg3)); } void test_case_5() { string Arr0[] = {"000","100","110"}; vector <string> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arr1[] = {3,18,1}; vector <int> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); int Arr2[] = {242949,8471,54403957}; vector <int> Arg2(Arr2, Arr2 + (sizeof(Arr2) / sizeof(Arr2[0]))); int Arg3 = 53867; int Arg4 = 16; verify_case(5, Arg4, minTime(Arg0, Arg1, Arg2, Arg3)); }// END CUT HERE};// BEGIN CUT HEREint main(void) { Farmville ___test; ___test.run_test(-1);// ___test.test_case_3(); system("pause");}// END CUT HERE
阅读全文
0 0
- [LP对偶][含正权环的最大费用流] SRM 676 div1 1000pts Farmville
- [LP对偶费用流] SRM 676 div1 Farmville
- [LP对偶 & 最大费用可行流] TopCoder SRM 676 div1 Farmville
- [LP对偶费用流] BZOJ 3112 [Zjoi2013]防守战线
- [费用流对偶LP 单纯形] HihoCoder #1464 Challenge 26 Rikka with Flow
- [LP对偶费用流] JAG Practice Contest 2015 J Longest Shortest Path
- SRM 676 div1 hard
- [差分 上下界最大流] SRM 694 div1 SRMDiv0Easy
- SRM 477 DIV1 1000
- CF190 DIV1 B Ciel and Duel 最大费用流
- 复杂度:零和博弈,最小最大定理以及LP对偶
- [TC SRM 571] DIV1 1000
- TopCoder SRM 474 DIV1 1000
- SRM 510 Div1 1000 TheLuckyBasesDivOne
- lp---对偶问题
- TC SRM 680(div 2) 1000pts
- TC SRM 683 Div2(1000pts)
- srm 181 div1 1000(状压dp)
- 这个HelloWorld有点长
- 安装系统后分区全部合并到C盘别的分区的文件怎样找到
- 二叉堆 删除 插入 调整 堆排序
- 【arduino】A4988驱动
- 在mybatis里面配置外部资源文件
- [LP对偶][含正权环的最大费用流] SRM 676 div1 1000pts Farmville
- dddddddd
- 如何更精准的找到你需要的开源库
- BZOJ 1101 Luogu P3455 POI 2007 Zap (莫比乌斯反演+分块)
- Ruby插入排序的常规写法和递归写法
- Java基础学习总结(1)—Java编程语言概述及环境搭建
- redis安装和redis集群配置
- 如何访问虚拟机(另一台设备)上运行的 Web 项目
- Linux下配置JDK