版权声明:小蒟蒻的博客转载也请注明出处哦 https://blog.csdn.net/qq_42835823/article/details/86624931
【NOI2008】志愿者招募
费用流+建图
就看看代码吧。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int inf=(1<<30);
const int N=1e3+10;
const int M=1e4+5;
struct edge{
int v,f,c,nxt;
}e[M<<2];
int first[N],cnt=1;
inline void add(int u,int v,int f,int c){
e[++cnt].v=v;e[cnt].f=f;e[cnt].c=c;
e[cnt].nxt=first[u];first[u]=cnt;
e[++cnt].v=u;e[cnt].f=0;e[cnt].c=-c;
e[cnt].nxt=first[v];first[v]=cnt;//
}
int n,m,a[N],vis[N],dis[N],s,t;
bool spfa(){
memset(vis,0,sizeof(vis));
memset(dis,0x3f,sizeof(dis));
deque<int>q;
q.push_back(t);
dis[t]=0;vis[t]=1;
while(!q.empty()){
int u=q.front();q.pop_front();vis[u]=0;
for(int i=first[u];i;i=e[i].nxt){
int v=e[i].v;
if(e[i^1].f>0&&dis[v]>dis[u]-e[i].c){//
dis[v]=dis[u]-e[i].c;
if(!vis[v]){
vis[v]=1;
if(!q.empty()&&dis[v]<dis[q.front()])q.push_front(v);
else q.push_back(v);
}
}
}
}
return dis[s]<0x3f3f3f3f;
}
int money=0;
int dfs(int x,int f){
if(x==t){vis[t]=1;return f;}
int used=0,k;vis[x]=1;
for(int i=first[x];i;i=e[i].nxt){
int v=e[i].v;
if(e[i].f<1||vis[v]||dis[x]!=dis[v]+e[i].c)continue;
k=dfs(v,min(e[i].f,f-used));//
if(!k)continue;
money+=k*e[i].c;
e[i].f-=k;e[i^1].f+=k;
used+=k;
if(used==f)break;
}
return used;
}
int ZKW(){
int flow=0;
while(spfa()){
vis[t]=1;
while(vis[t]){
memset(vis,0,sizeof(vis));
flow+=dfs(s,inf);
}
}
return flow;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=2;i<=n+1;i++)add(i,i-1,inf,0);//
for(int i=1;i<=m;i++){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
add(u,v+1,inf,w);
}
s=0;t=n+2;
for(int i=1;i<=n+1;i++){
int c=a[i]-a[i-1];
if(c>0)add(s,i,c,0);
if(c<0)add(i,t,-c,0);
}
ZKW();
printf("%d",money);
return 0;
}