大部分内容转自: 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; }