想必大家都看过成龙大哥的《80天环游世界》,里面的紧张刺激的打斗场面一定给你留下了深刻的印象。现在就有这么
一个80人的团伙,也想来一次环游世界。
他们打算兵分多路,游遍每一个国家。
因为他们主要分布在东方,所以他们只朝西方进军。设从东方到西方的每一个国家的编号依次为1...N。假若第i个人的游历路线为P1、P2......Pk(0≤k≤N),则P1
众所周知,中国相当美丽,这样在环游世界时就有很多人经过中国。我们用一个正整数Vi来描述一个国家的吸引程度,Vi值越大表示该国家越有吸引力,同时也表示有且仅
有Vi个人会经过那一个国家。
为了节省时间,他们打算通过坐飞机来完成环游世界的任务。同时为了省钱,他们希望总的机票费最小。
明天就要出发了,可是有些人临阵脱逃,最终只剩下了M个人去环游世界。他们想知道最少的总费用,你能告诉他们吗?
Input
第一行两个正整数N,M。
第二行有N个不大于M正整数,分别表示V1,V2......VN。
接下来有N-1行。第i行有N-i个整数,该行的第j个数表示从第i个国家到第i+j个国家的机票费(如果该值等于-1则表示这两个国家间没有通航)。
Output
在第一行输出最少的总费用。
Sample Input
6 3
2 1 3 1 2 1
2 6 8 5 0
8 2 4 1
6 1 0
4 -1
4
2 1 3 1 2 1
2 6 8 5 0
8 2 4 1
6 1 0
4 -1
4
Sample Output
27
HINT
1<= N < =100 1<= M <= 79
Source
题解:有上下界的费用流
其实有上下界的费用流与有上下界的可行流处理的方式差不多。
对于有上下界的费用流问题我们可以先建立原图,在原图的基础上添加附加源汇,对于流量限制的下界不为0的边处理的方式与有上下界的可行流的处理方式相同。
然后在重构图的基础上正常跑费用流就可以了。
#include
#include
#include
#include
#include
#define N 50003
#define inf 1000000000
using namespace std;
int n,m,tot,ans;
int point[N],v[N],next[N],remain[N],c[N],last[N];
int dis[N],can[N],d[N];
void add(int x,int y,int z,int k)
{
tot++; next[tot]=point[x]; point[x]=tot; v[tot]=y; remain[tot]=z; c[tot]=k;
tot++; next[tot]=point[y]; point[y]=tot; v[tot]=x; remain[tot]=0; c[tot]=-k;
// cout< p; p.push(s);
while (!p.empty()){
int now=p.front(); p.pop();
for (int i=point[now];i!=-1;i=next[i])
if (remain[i]&&dis[v[i]]>dis[now]+c[i]){
dis[v[i]]=dis[now]+c[i];
last[v[i]]=i;
if (!can[v[i]]) {
can[v[i]]=1;
p.push(v[i]);
}
}
can[now]=0;
}
if (dis[t]==inf) return false;
int mx=addflow(s,t);
ans+=mx*dis[t];
return true;
}
void solve(int s,int t)
{
while (spfa(s,t));
}
int main()
{
freopen("a.in","r",stdin);
scanf("%d%d",&n,&m);
tot=-1;
memset(point,-1,sizeof(point));
for (int i=1;i<=n;i++) {
int x; scanf("%d",&x);
add(i,i+n,0,0);
d[i]-=x; d[i+n]+=x;
}
int S=201; int T=202;
add(0,S,m,0);
for (int i=1;i<=n;i++) add(S,i,inf,0);
for (int i=1;i<=n;i++)
for (int j=i+1;j<=n;j++) {
int x; scanf("%d",&x);
if (x!=-1)
add(i+n,j,inf,x);
}
for (int i=1;i<=2*n;i++)
if (d[i]>0) add(0,i,d[i],0);
else add(i,T,-d[i],0);
solve(0,T);
printf("%d\n",ans);
}