BZOJ 2055(80人环游世界-上下界网络流)

来源:互联网 发布:linux 系统log 编辑:程序博客网 时间:2024/04/27 22:35

Description

想必大家都看过成龙大哥的《80天环游世界》,里面的紧张刺激的打斗场面一定给你留下了深刻的印象。现在就有这么一个80人的团伙,也想来一次环游世界。他们打算兵分多路,游遍每一个国家。因为他们主要分布在东方,所以他们只朝西方进军。设从东方到西方的每一个国家的编号依次为1...N。假若第i个人的游历路线为P1、P2......Pk(0≤k≤N),则P1<P2<......<Pk。众所周知,中国相当美丽,这样在环游世界时就有很多人经过中国。我们用一个正整数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 32 1 3 1 2 12 6 8 5 08 2 4 16 1 04 -14   

Sample Output

27

HINT

1<= N < =100 1<= M <= 79

拆点建图,上下界网络流

#include<cstdio>#include<cstring>#include<cstdlib>#include<algorithm>#include<functional>#include<iostream>#include<cmath>#include<cctype>#include<ctime>using namespace std;#define For(i,n) for(int i=1;i<=n;i++)#define Fork(i,k,n) for(int i=k;i<=n;i++)#define Rep(i,n) for(int i=0;i<n;i++)#define ForD(i,n) for(int i=n;i;i--)#define RepD(i,n) for(int i=n;i>=0;i--)#define Forp(x) for(int p=pre[x];p;p=next[p])#define Forpiter(x) for(int &p=iter[x];p;p=next[p])  #define Lson (x<<1)#define Rson ((x<<1)+1)#define MEM(a) memset(a,0,sizeof(a));#define MEMi(a) memset(a,128,sizeof(a));#define INF (2139062143)#define F (100000007)#define MAXN (500+10)#define MAXM ((100*3+10000)*12+10)#define MAXAi (35000)#define eps (1e-3)long long mul(long long a,long long b){return (a*b)%F;}long long add(long long a,long long b){return (a+b)%F;}long long sub(long long a,long long b){return (a-b+(a-b)/F*F+F)%F;}typedef long long ll;class Cost_Flow  {  public:      int n,s,t;      int q[MAXM];      int edge[MAXM],next[MAXM],pre[MAXN],weight[MAXM],size;      int cost[MAXM];      void addedge(int u,int v,int w,int c)        {            edge[++size]=v;            weight[size]=w;            cost[size]=c;            next[size]=pre[u];            pre[u]=size;        }        void addedge2(int u,int v,int w,int c){addedge(u,v,w,c),addedge(v,u,0,-c);}       bool b[MAXN];      int d[MAXN];      int pr[MAXN],ed[MAXN];      bool SPFA(int s,int t)        {            For(i,n) d[i]=INF,b[i]=0;         d[q[1]=s]=0;b[s]=1;            int head=1,tail=1;            while (head<=tail)            {                int now=q[head++];                Forp(now)                {                    int &v=edge[p];                    if (weight[p]&&d[now]+cost[p]<d[v])                    {                        d[v]=d[now]+cost[p];                        if (!b[v]) b[v]=1,q[++tail]=v;                        pr[v]=now,ed[v]=p;                    }                }                b[now]=0;            }            return d[t]!=INF;        }       int totcost;        int CostFlow(int s,int t)        {            int maxflow=0;        while (SPFA(s,t))            {                int flow=INF;                for(int x=t;x^s;x=pr[x]) flow=min(flow,weight[ed[x]]);             totcost+=flow*d[t];             maxflow+=flow;               for(int x=t;x^s;x=pr[x]) weight[ed[x]]-=flow,weight[ed[x]^1]+=flow;                 }    //        cout<<maxflow<<endl;        return totcost;        }        void mem(int n,int t)      {          (*this).n=n;          size=1;          totcost=0;          MEM(pre) MEM(next)       }  }S1;  int read(){    int x=0,f=1; char ch=getchar();    while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}    while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}    return x*f;} int n,m;int main(){//  freopen("bzoj2055.in","r",stdin);//  freopen(".out","w",stdout);    n=read();m=read();    int s=2*n+1,t=s+1,S=t+1,T=S+1;    S1.mem(T,T);    const int inf = INF;    For(i,n) {        int v=read();               S1.addedge2(s,i,inf,0);        S1.addedge2(n+i,t,inf,0);        S1.addedge2(S,i+n,v,0);        S1.addedge2(i,T,v,0);    }    For(i,n) {        Fork(j,i+1,n) {            int c=read();            if (c==-1) continue;            S1.addedge2(i+n,j,inf,c);        }    }     S1.addedge2(t,s,m,0); //无源无汇,保证流量守恒    cout<<S1.CostFlow(S,T)<<endl;     return 0;}
0 0
原创粉丝点击