大部分内容转自: BYVOID - NOI2008 志愿者招募
如果讲道理的话,就是说我们抽象一下这个模型……然后每条费用边就是连接起始日期和结束日期的边,也就是说这条边上的流量增加1,就要增加一个这段时间的工人。然后因为有无穷边,那么所有限制流量的边必然满流。因此答案正确。
/**************************************************************
Problem: 1061
User: whzzt
Language: C++
Result: Accepted
Time:1652 ms
Memory:1884 kb
****************************************************************/
#include"iostream"
#include"stdio.h"
#include"algorithm"
#include"stdlib.h"
using namespace std;
const int N=1005,M=10005,oo=(int)2e9;
int n,m,S,T; typedef long long ll;
struct Edge {
int next,v;
int flow,cost;
Edge * Back;
} edge[3*M];
int need[N],head[N],cnt;
ll ans;
inline void addedge(int u,int v,int flow,int cost){
Edge e0={head[u],v,flow,cost,NULL},e1={head[v],u,0,-cost,NULL};
head[u]=++cnt; head[v]=++cnt;
e0.Back=&edge[cnt]; e1.Back=&edge[cnt-1];
edge[cnt-1]=e0; edge[cnt]=e1;
}
void init_and_build(){
int i,a,b,c;
for (i=1;i<=n;i++)
{ scanf("%d",need+i);}
for (i=1;i<=m;i++)
{ scanf("%d%d%d",&a,&b,&c);
addedge(a,b+1,oo,c);}
for (i=1;i<=n+1;i++)
if(need[i]-need[i-1]>0)
addedge(S,i,need[i]-need[i-1],0);
else
addedge(i,T,need[i-1]-need[i],0);
for (i=1;i<=n;i++) addedge(i+1,i,oo,0);
}
int que[N],*l,*r,*OF;
inline int * add(int *p)
{ return ++p==OF?que:p;}
bool vis[N]; int path[N]; ll dis[N];
inline int spfa(){
l=que+1,r=que; int i;
for (i=S;i<=T;i++) dis[i]=oo*(ll)oo;
*(++r)=S; vis[S]=true; dis[S]=0; path[T]=0;
while(l!=(r+1==OF?que:r+1))
{
int k=*l; l=add(l); vis[k]=false;
for (i=head[k];i;i=edge[i].next)
{
if(edge[i].flow&&dis[edge[i].v]>dis[k]+edge[i].cost)
{
dis[edge[i].v]=dis[k]+edge[i].cost;
path[edge[i].v]=i;
if(vis[edge[i].v]==false)
{ vis[edge[i].v]=true;
r=add(r); *r=edge[i].v;}
}
}
}
return path[T];
}
ll GetFlow(){
int Flow=oo,k; ll t=0;
for (k=T;path[k];k=edge[path[k]].Back->v)
{ Flow=min(Flow,edge[path[k]].flow);}
for (k=T;path[k];k=edge[path[k]].Back->v)
{ t+=Flow*(ll)edge[path[k]].cost;
edge[path[k]].flow-=Flow;
edge[path[k]].Back->flow+=Flow;}
return t;
}
void work_and_solve(){
while (spfa())
ans+=GetFlow();
cout<<ans<<endl;
}
int main(){
scanf("%d%d",&n,&m);
S=0,T=n+2,OF=que+N-1;
init_and_build();
work_and_solve();
return 0;
}