[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
原创粉丝点击