• 【BZOJ2055】80人环游世界 有上下界费用流


    【BZOJ2055】80人环游世界

    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 3
    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

    题解:有上下界费用流,需要拆点,直接上建边方法

    1.S -> i的出点 容量v[i],费用0 相当于(i的入点->i的出点)这条边的下界
    2.i的入点 -> T 容量v[i],费用0 也相当于这条边的下界
    由于(i的入点 -> i的出点)这条边的上界=下界,所以不需要再原图中连(i的入点 ->i的出点)这条边了
    3.0的出点 -> i的入点 容量m,费用0 相当于可以在任意一个点开始
    4.i的出点 -> 0的入点 容量m,费用0 相当于可以在任意一个点终止
    5.0的入点 -> 0的出点 容量m,费用0 为了使原图每个点入度=出度
    下面,对于原图中的边(i,j)
    6.i的出点 -> j的入点 容量∞,费用为i到j的机票费

    #include <cstdio>
    #include <iostream>
    #include <queue>
    #include <cstring>
    using namespace std;
    int n,m,cnt,S,T,SS,TT,ans;
    int to[300000],next[300000],cost[300000],flow[300000],head[300],dis[300],inq[300],pe[300],pv[300];
    int ind[300000],outd[300000];
    queue<int> q;
    void add(int a,int b,int c,int d)
    {
    	to[cnt]=b,cost[cnt]=c,flow[cnt]=d,next[cnt]=head[a],head[a]=cnt++;
    	to[cnt]=a,cost[cnt]=-c,flow[cnt]=0,next[cnt]=head[b],head[b]=cnt++;
    }
    int rd()
    {
    	int ret=0,f=1;	char gc=getchar();
    	while(gc<'0'||gc>'9')	{if(gc=='-')f=-f;	gc=getchar();}
    	while(gc>='0'&&gc<='9')	ret=ret*10+gc-'0',gc=getchar();
    	return ret*f;
    }
    int bfs()
    {
    	memset(dis,0x3f,sizeof(dis));
    	q.push(S),dis[S]=0;
    	int i,u;
    	while(!q.empty())
    	{
    		u=q.front(),q.pop(),inq[u]=0;
    		for(i=head[u];i!=-1;i=next[i])
    		{
    			if(dis[to[i]]>dis[u]+cost[i]&&flow[i])
    			{
    				dis[to[i]]=dis[u]+cost[i],pe[to[i]]=i,pv[to[i]]=u;
    				if(!inq[to[i]])	inq[to[i]]=1,q.push(to[i]);
    			}
    		}
    	}
    	return dis[T]<0x3f3f3f3f;
    }
    int main()
    {
    	n=rd(),m=rd();
    	int i,j,a,b,c;
    	memset(head,-1,sizeof(head));
    	S=2*n+1,T=2*n+2,SS=2*n+3,TT=2*n+4;
    	for(i=1;i<=n;i++)
    	{
    		a=rd();
    		add(S,i+n,0,a),add(i,T,0,a),add(SS,i,0,m),add(i+n,TT,0,m);
    	}
    	add(TT,SS,0,m);
    	for(i=1;i<n;i++)
    	{
    		for(j=i+1;j<=n;j++)
    		{
    			a=rd();
    			if(a!=-1)	add(i+n,j,a,1<<30);
    		}
    	}
    	while(bfs())
    	{
    		int mf=1<<30;
    		for(i=T;i!=S;i=pv[i])	mf=min(mf,flow[pe[i]]);
    		ans+=mf*dis[T];
    		for(i=T;i!=S;i=pv[i])	flow[pe[i]]-=mf,flow[pe[i]^1]+=mf;
    	}
    	printf("%d",ans);
    	return 0;
    }
  • 相关阅读:
    html知识点
    BFC的布局规则以及触发条件
    父元素与子元素之间的margin-top问题(css hack)
    加overflow-hidden就可以解决高度塌陷问题,overflow-触发BFC
    子元素margin-top为何会影响父元素?
    子div设置margin-top使得父div也跟着向下移动
    vue 之 mongodb安装问题
    vue 之 nginx原理(webpack环境下配置)
    vue 之 PC端项目配置
    ASP.NET CORE (一)
  • 原文地址:https://www.cnblogs.com/CQzhangyu/p/6831864.html
Copyright © 2020-2023  润新知