二分答案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].v
inline 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 HERE
int main(){
Farmville ___test;
___test.run_test(-1);
getch() ;
return 0;
}
// END CUT HERE