[LP对偶费用流] SRM 676 div1 Farmville
来源:互联网 发布:知る是几段动词 编辑:程序博客网 时间:2024/06/06 21:57
二分答案T之后转化成求最小费用
加超级源和超级汇
记每个植物生长的时间为xi,结束的时间为yi,减少的时间为di。
那么限制为 yi>=xi+ti-di, yi>=xi,xj>=yi, ys+T>=xt, 最小化sum di*ci
然后直接对偶成最大费用循环流
在目标函数中不存在的,把权值设为inf
// BEGIN CUT HERE #include<conio.h>#include<sstream>// END CUT HERE #include<cstdio>#include<cstdlib>#include<cstring>#include<cmath>#include<iostream>#include<algorithm>#include<vector>#include<map>#include<string>#include<set>#define cl(x) memset(x,0,sizeof(x))using namespace std;typedef long long ll;const int N=1005;const int M=100005;struct edge{ int u,v,w,f,next;}G[M];int head[N],inum=1;#define V G[p].vinline void add(int u,int v,int w,int f,int p){ G[p].u=u; G[p].v=v; G[p].w=w; G[p].f=f; G[p].next=head[u]; head[u]=p;}inline void link(int u,int v,int w,int f){ add(u,v,w,f,++inum),add(v,u,-w,0,++inum);}inline void clear(){ cl(head); inum=1;}int S,T;ll dis[N]; int pre[N],ins[N];int Q[1000005],l,r;ll Mincost;inline bool SPFA(){ for (int i=1;i<=T;i++) dis[i]=-1LL<<60,pre[i]=0,ins[i]=0; l=r=-1; dis[S]=0; Q[++r]=S; ins[S]=1; while (l<r){ int u=Q[++l]; ins[u]=0; for (int p=head[u];p;p=G[p].next) if (G[p].f && dis[V]<dis[u]+G[p].w){ dis[V]=dis[u]+G[p].w; pre[V]=p; if (!ins[V]) Q[++r]=V,ins[V]=1; } } if (dis[T]==-1LL<<60) return 0; int minv=1<<30; for (int p=pre[T];p;p=pre[G[p].u]) minv=min(minv,G[p].f); Mincost+=dis[T]*minv; for (int p=pre[T];p;p=pre[G[p].u]) G[p].f-=minv,G[p^1].f+=minv; return 1;}int n,t[55],c[55];char Map[55][55];int bg;#define x(i) ((i)*2-1)#define y(i) ((i)*2)inline bool check(int mid){ clear(); int s,t; s=2*n+1,t=2*n+2,S=2*n+3,T=2*n+4; for (int i=1;i<=n;i++) link(s,x(i),0,1<<30),link(y(i),t,0,1<<30); link(t,s,-mid,1<<30); for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) if (i!=j && Map[j][i]=='1') link(y(i),x(j),0,1<<30); Mincost=0; int tmp=inum; for (int i=1;i<=n;i++){ link(S,y(i),0,c[i]),link(x(i),T,0,c[i]),link(y(i),x(i),-::t[i],c[i]),Mincost+=(ll)c[i]*::t[i]; link(x(i),y(i),0,1<<30); } while (SPFA()); return Mincost<=bg;}class Farmville{public: int minTime(vector <string> s, vector <int> time, vector <int> cost, int budget){ n=s.size(); for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) Map[i][j]=s[i-1][j-1]; int sum=0; for (int i=1;i<=n;i++) t[i]=time[i-1],c[i]=cost[i-1],sum+=t[i]; bg=budget; int L=-1,R=sum,MID; while (L+1<R) if (check(MID=(L+R)>>1)) R=MID; else L=MID; return R; }// 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(){ Farmville ___test; ___test.run_test(-1); getch() ; return 0;}// END CUT HERE
阅读全文
0 0
- [LP对偶费用流] SRM 676 div1 Farmville
- [LP对偶 & 最大费用可行流] TopCoder SRM 676 div1 Farmville
- [LP对偶][含正权环的最大费用流] SRM 676 div1 1000pts 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
- lp---对偶问题
- 【原始对偶费用流ver2.0】hdu4744
- 【topcoder】570div1 900 CurvyonRails【费用流】
- SRM 465(DIV1 DIV2)
- SRM 465(DIV1 DIV2)
- SRM 144 DIV1 second
- SRM 507 DIV1 B
- SRM 513 DIV1 C
- SRM 500 DIV1 B
- 1-SRM 144 DIV1
- TC SRM 559 DIV1
- WiFi-Pumpkin无线渗透测试框架实战教程
- ashmem 使用
- dyld: Symbol not found: _OBJC_CLASS_$_SFRequestLogin
- lightoj 1138
- 欢迎使用CSDN-markdown编辑器
- [LP对偶费用流] SRM 676 div1 Farmville
- 【POJ】3140 Contestants Division 树形dp
- 移除GrowingIo导致app崩溃
- (window.ActiveXObject)
- SSM整合之数据回显
- 1.2 你应该了解的轨至轨输入
- 使用KNN算法手写体识别
- php用GD库给图片添加水印
- 1.3 Swinging Close to Ground—single supply operation