标签:招募 int 努力 tput include 设计 资源 lib nbsp
仅包含一个整数,表示你所设计的最优方案的总费用。
1 ≤ N ≤ 1000,1 ≤ M ≤ 10000,题目中其他所涉及的数据均 不超过2^31-1。
正解:不知道。。据说原本的正解线性规划被hack掉了。。
然而我连线性规划都不会,所以写了一个naive的费用流。。学了以后再来填坑吧。。
考虑从原点向第0天连容量为inf,费用为0的边,第i天向第i+1天连容量为inf-a[i],费用为0的边,我们把这条线称之为主线。第n天向汇点连容量为inf,费用为0的边。对于每一段区间,从第s-1天到第t天连容量为inf,费用为c的边,我们把这条线称为副线。那么跑费用流时,主线上的堵塞流就自动地转移到副线上,同时,副线又因为有费用,那么我们就可以算出最小的费用了。
//It is made by wfj_2048~ #include <algorithm> #include <iostream> #include <complex> #include <cstring> #include <cstdlib> #include <cstdio> #include <vector> #include <cmath> #include <queue> #include <stack> #include <map> #include <set> #define inf (1<<29) #define il inline #define RG register #define ll long long #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout) using namespace std; struct edge{ int nt,to,flow,cap,cost; }g[30010]; queue <int> Q; int head[1010],dis[1010],flow[1010],fa[1010],p[1010],a[1010],n,m,S,T,num=1,cost; il int gi(){ RG int x=0,q=1; RG char ch=getchar(); while ((ch<‘0‘ || ch>‘9‘) && ch!=‘-‘) ch=getchar(); if (ch==‘-‘) q=-1,ch=getchar(); while (ch>=‘0‘ && ch<=‘9‘) x=x*10+ch-48,ch=getchar(); return q*x; } il void insert(RG int from,RG int to,RG int cap,RG int cost){ g[++num]=(edge){head[from],to,0,cap,cost},head[from]=num; } il int bfs(RG int S,RG int T){ for (RG int i=1;i<=n+3;++i) dis[i]=inf; Q.push(S),flow[S]=inf,dis[S]=0; while (!Q.empty()){ RG int x=Q.front(),v; Q.pop(); for (RG int i=head[x];i;i=g[i].nt){ v=g[i].to; if (dis[v]>dis[x]+g[i].cost && g[i].cap>g[i].flow){ flow[v]=min(flow[x],g[i].cap-g[i].flow); dis[v]=dis[x]+g[i].cost; fa[v]=x,p[v]=i,Q.push(v); } } } if (dis[T]==inf) return 0; cost+=flow[T]*dis[T]; for (RG int x=T;x!=S;x=fa[x]) g[p[x]].flow+=flow[T],g[p[x]^1].flow-=flow[T]; return 1; } il int mcmf(RG int S,RG int T){ cost=0; while (bfs(S,T)); return cost; } il void work(){ n=gi(),m=gi(); S=n+2,T=n+3; insert(S,1,inf,0),insert(1,S,0,0); for (RG int i=1;i<=n;++i) a[i]=gi(),insert(i,i+1,inf-a[i],0),insert(i+1,i,0,0); for (RG int i=1;i<=m;++i){ RG int s=gi(),t=gi(),c=gi(); insert(s,t+1,inf,c),insert(t+1,s,0,-c); } insert(n+1,T,inf,0),insert(T,n+1,0,0); printf("%d\n",mcmf(S,T)); return; } int main(){ File("volunteer"); work(); return 0; }
标签:招募 int 努力 tput include 设计 资源 lib nbsp
原文地址:http://www.cnblogs.com/wfj2048/p/6428248.html