Description
![](http://www.lydsy.com/JudgeOnline/images/1520_1.jpg)
Input
![](http://www.lydsy.com/JudgeOnline/images/1520_2.jpg)
Output
如果有可行解, 输出最小代价,否则输出NIE.
Sample Input
5
1 1 2 3
1 1 5 1
3 2 5 5
4 1 5 10
3 3 3 1
1 1 2 3
1 1 5 1
3 2 5 5
4 1 5 10
3 3 3 1
Sample Output
9
最小费用最大流,满流即有合法解
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<cstring>
#define st (2*n+1)
#define en (2*n+2)
using namespace std;
int fi[405],ne[200000],j[200000],k[200000],c[200000],step=1;
int n,l,r,co,m,ans,minn,sum;
int que[200000],tot,tow,dis[405],bian[405],fa[405];
bool flag[405];
inline void addedge(int fr,int to,int flow,int cost){
j[++step]=to;k[step]=flow;c[step]=cost;
ne[step]=fi[fr];fi[fr]=step;
j[++step]=fr;k[step]=0;c[step]=-cost;
ne[step]=fi[to];fi[to]=step;
}
inline bool spfa(){
memset(dis,60,sizeof(dis));
que[tot=tow=1]=st;dis[st]=0;
while (tot<=tow){
flag[que[tot]]=0;
for (int u=fi[que[tot]];u;u=ne[u])
if (dis[j[u]]>dis[que[tot]]+c[u] && k[u]>0){
dis[j[u]]=dis[que[tot]]+c[u];
bian[j[u]]=u;
fa[j[u]]=que[tot];
if (!flag[j[u]]){
flag[j[u]]=1;
que[++tow]=j[u];
}
}
++tot;
}
if (dis[en]==dis[0])return false;
minn=1e9;
for (int i=en;i!=st;i=fa[i])
minn=min(minn,k[bian[i]]);
sum+=minn;
for (int i=en;i!=st;i=fa[i]){
k[bian[i]]-=minn;
k[bian[i]^1]+=minn;
ans+=c[bian[i]];
}
return true;
}
int main (){
scanf ("%d",&n);
for (int i=1;i<=n;++i){
scanf ("%d%d%d%d",&m,&l,&r,&co);
addedge(st,i,1,0);
addedge(n+i,en,1,0);
for (int q=l;q<=r;++q)
addedge(i,n+q,1,abs(q-m)*co);
}
while (spfa());
if (sum==n)printf ("%d",ans);
else puts("NIE");
return 0;
}