题目模型出的真心神。
需要好难才能推出来。
本来打算写一篇好的题解,但是状态实在不好,没弄会这道题。
只能先扒建边留个坑了。
据说“单纯形算法”可以高速+裸建图 水过此题(呃,或曰此题乃单纯形裸题是也。)
留坑前先给个链接吧,应该是目前网上最好的此题题解:
BYV大神的题解:www.byvoid.com/blog/noi-2008-employee/#more-916
我的代码:
<span style="font-family:KaiTi_GB2312;font-size:18px;">#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 1050
#define M 30100
#define P 105
#define inf 0x3f3f3f3f
using namespace std;
struct KSD
{
int u,v,len,fee,next;
}e[M];
int head[N],cnt;
void add(int u,int v,int len,int fee)
{
cnt++;
e[cnt].u=u;
e[cnt].v=v;
e[cnt].len=len;
e[cnt].fee=fee;
e[cnt].next=head[u];
head[u]=cnt;
}
int s,t,dist[N];
int pre[N],lim[N];
bool in[N];
queue<int>q;
void spfa()
{
memset(dist,0x3f,sizeof(dist));
memset(lim,0,sizeof(lim));
while(!q.empty())q.pop();
int i,u,v;
dist[s]=0,in[s]=1;
lim[s]=inf;
q.push(s);
while(!q.empty())
{
u=q.front(),q.pop(),in[u]=0;
for(i=head[u];i;i=e[i].next)
{
v=e[i].v;
if(!e[i].len)continue;
if(dist[v]>dist[u]+e[i].fee)
{
dist[v]=dist[u]+e[i].fee;
lim[v]=min(e[i].len,lim[u]);
pre[v]=i;
if(!in[v])
{
in[v]=1;
q.push(v);
}
}
}
}
return ;
}
void handle(int flow)
{
for(int i=pre[t];i;i=pre[e[i].u])
{
e[i].len-=flow;
e[i^1].len+=flow;
}
}
int n,m,minfee;
int need[N];
int main()
{
// freopen("test.in","r",stdin);
int i,a,b,c;
scanf("%d%d",&n,&m),n++;
s=n+1,t=n+2,cnt=1;
for(i=1;i<n;i++)scanf("%d",&need[i]);
for(i=1;i<=m;i++)
{
scanf("%d%d%d",&a,&b,&c);
add(a,b+1,inf,c),add(b+1,a,0,-c);
}
for(i=1;i<=n;i++)
{
c=need[i]-need[i-1];
if(c>=0)add(s,i,c,0),add(i,s,0,0);
else add(i,t,-c,0),add(t,i,0,0);
if(i>1)add(i,i-1,inf,0),add(i-1,i,0,0);
}
while(spfa(),dist[t]<inf)
{
minfee+=dist[t]*lim[t];
handle(lim[t]);
}
printf("%d\n",minfee);
return 0;
}
</span>