zoukankan      html  css  js  c++  java
  • codevs1033 蚯蚓的游戏问题

    题目描述 Description

    在一块梯形田地上,一群蚯蚓在做收集食物游戏。蚯蚓们把梯形田地上的食物堆积整理如下:

                                                     a(1,1)  a(1,2)…a(1,m)

                                              a(2,1)  a(2,2)  a(2,3)…a(2,m)  a(2,m+1)     

                                         a(3,1)  a (3,2)  a(3,3)…a(3,m+1)  a(3,m+2)

                                 ……  

                                       a(n,1)   a(n,2)   a(n,3)…           a(n,m+n-1)     

           它们把食物分成n行,第1行有m堆的食物,每堆的食物量分别是a(1,1),a(1,2),…,a(1,m);

    第2行有m+1堆食物,每堆的食物量分别是a(2,1),a(2,2),…,  a(2,m+1);以下依次有m+2堆、m+3堆、…m+n-1堆食物。

    现在蚯蚓们选择了k条蚯蚓来测试它们的合作能力(1≤ k ≤m)。测试法如下:第1条蚯蚓从第1行选择一堆食物,然后往左下或右下爬,并收集1堆食物,例如从a(1,2)只能爬向a(2,2) 或a(2,3),而不能爬向其它地方。接下来再爬向下一行收集一堆食物,直到第n行收集一堆食物。第1条蚯蚓所收集到的食物量是它在每一行所收集的食物量之和;第2条蚯蚓也从第1行爬到第n行,每行收集一堆食物,爬的方法与第1条蚯蚓相类似,但不能碰到第1条蚯蚓所爬的轨迹;一般地,第i 条蚯蚓从第1行爬到第 n行,每行收集一堆食物,爬的方法与第1条蚯蚓类似,但不能碰到前 I-1 条蚯蚓所爬的轨迹。这k条蚯蚓应该如何合作,才能使它们所收集到的食物总量最多?收集到的食物总量可代表这k条蚯蚓的合作水平。

    • Ø编程任务:

           给定上述梯形m、n和k的值(1≤k≤m≤30;1≤n≤30)以及梯形中每堆食物的量(小于10的非整数),编程计算这k条蚯蚓所能收集到的食物的最多总量。

    输入描述 Input Description

           输入数据由文件名为INPUT1.*的文本文件提供,共有n+1行。每行的两个数据之间用一个空格隔开。

            ●第1行是n、m和k的值。

    • 接下来的n行依次是梯形的每一行的食物量a(i,1),a(i,2),…,a(i,m+i-1),i=1,2,…,n。
    输出描述 Output Description

    程序运行结束时,在屏幕上输出k蚯蚓条所能收集到的食物的最多总量。

    样例输入 Sample Input

    3    2   2    

    1   2

    5   0   2

    1   10  0  6

    样例输出 Sample Output

    26

    拆点 费用流

    //Serene
    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<cstdio>
    #include<cmath>
    using namespace std;
    const int maxn=2*30*60+10,maxm=4*maxn+maxn,INF=0x3f3f3f3f;
    int n,m,k,tu[maxn],S,T,YY;
    
    int aa;char cc;
    int read() {
    	aa=0;cc=getchar();
    	while(cc<'0'||cc>'9') cc=getchar();
    	while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
    	return aa;
    }
    
    struct Node{
    	int x,y,cap,flow,w;
    	Node(){}
    	Node(int x,int y,int cap,int w) :x(x),y(y),cap(cap),w(w){}
    }node[2*maxm];
    
    int fir[maxn],nxt[2*maxm],e=1;
    void add(int x,int y,int z,int w) {
    	node[++e]=Node(x,y,z,w); nxt[e]=fir[x];fir[x]=e;
    	node[++e]=Node(y,x,0,-w); nxt[e]=fir[y];fir[y]=e;
    }
    
    int zz[maxn],from[maxn],dis[maxn];bool vis[maxn];
    bool spfa() {
    	int s=1,t=0,x,y,z;
    	memset(dis,-1,sizeof(dis));
    	memset(zz,0,sizeof(zz));
    	zz[++t]=S;vis[S]=1;dis[S]=0;
    	while(s<=t) {
    		x=zz[s%maxn];
    		for(y=fir[x];y;y=nxt[y]) {
    			z=node[y].y;
    			if(dis[z]>=dis[x]+node[y].w||node[y].flow>=node[y].cap) continue;
    			if(!vis[z]) {
    				t++; zz[t%maxn]=z;
    				vis[z]=1;
    			}
    			from[z]=y;
    			dis[z]=dis[x]+node[y].w;
    		}
    		vis[x]=0;s++;
    	}
    	return dis[T]!=-1;
    }
    
    int MCMF() {
    	int rs=0,now=k;
    	while(spfa()&&k) {
    		now=k;
    		for(int i=T;i!=S;i=node[from[i]].x) now=min(now,node[from[i]].cap-node[from[i]].flow);
    		now=min(now,k);k-=now;
    		for(int i=T;i!=S;i=node[from[i]].x) {
    			node[from[i]].flow+=now;
    			node[from[i]^1].flow-=now;
    			rs+=now*node[from[i]].w;
    		}
    	}
    	return rs;
    }
    
    int main() {
    	n=read();m=read();k=read();int x,tot=0;
    	for(int i=1;i<=n*(2*m+n-1)/2;++i) tu[i]=read(),YY++;
    	S=2*YY+1;T=S+1;
    	for(int i=1;i<=n;++i) for(int j=1;j<=m+i-1;++j) {
    		x=++tot;
    		add(x+YY,x,1,tu[x]);
    		if(i!=n) {
    			add(x,x+YY+m+i-1,1,0);
    			add(x,x+YY+m+i,1,0);
    		}
    	}
    	for(int i=1;i<=m;++i) add(S,i+YY,1,0);
    	for(int i=tot;i>tot-n-m+1;--i) add(i,T,1,0);
    	printf("%d",MCMF());
    	return 0;
    }
    

      

    弱者就是会被欺负呀
  • 相关阅读:
    Linux 设备驱动 Edition 3(中文版)
    内核和用户空间共享内存的实现例程proc和mmap
    mmap的详细使用(用户空间)
    使用 I/O 内存from LDD3
    关于strcpy、memset、memcpy的使用详解
    get_free_page 和其友
    Linux调试技术介绍
    关于信息时代的学习
    [恢]hdu 1196
    [恢]hdu 1157
  • 原文地址:https://www.cnblogs.com/Serene-shixinyi/p/7445478.html
Copyright © 2011-2022 走看看