zoukankan      html  css  js  c++  java
  • luogu P1361 小M的作物 |网络流

    题目描述

    小M在MC里开辟了两块巨大的耕地A和B(你可以认为容量是无穷),现在,小P有n中作物的种子,每种作物的种子有1个(就是可以种一棵作物)(用1...n编号)。

    现在,第i种作物种植在A中种植可以获得ai的收益,在B中种植可以获得bi的收益,而且,现在还有这么一种神奇的现象,就是某些作物共同种在一块耕地中可以获得额外的收益,小M找到了规则中共有m种作物组合,第i个组合中的作物共同种在A中可以获得c1i的额外收益,共同总在B中可以获得c2i的额外收益。

    小M很快的算出了种植的最大收益,但是他想要考考你,你能回答他这个问题么?

    输入格式

    第一行包括一个整数n

    第二行包括n个整数,表示ai第三行包括n个整数,表示bi第四行包括一个整数m接下来m行,

    对于接下来的第i行:第一个整数ki,表示第i个作物组合中共有ki种作物,

    接下来两个整数c1i,c2i,接下来ki个整数,表示该组合中的作物编号。

    输出格式

    只有一行,包括一个整数,表示最大收益


    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    using namespace std;
    inline int read(){
        int s = 0, w = 1; char ch = getchar();
        while(ch < '0' || ch > '9'){ if(ch == '-') w = -1; ch = getchar();}
        while(ch >= '0' && ch <= '9') s = s * 10 + ch - '0', ch = getchar();
        return s * w;
    }
    const int N=500005,M=10*N,inf=1<<30;
    int nxt[M],head[N],go[M],edge[M],tot=1;
    inline void add(int u,int v,int w){
    	nxt[++tot]=head[u],head[u]=tot,go[tot]=v,edge[tot]=w;
    	nxt[++tot]=head[v],head[v]=tot,go[tot]=u,edge[tot]=0;
    }
    int n,m,s,t,maxflow=0;
    int d[N];
    inline bool bfs(){
    	memset(d,0,sizeof(d));
    	queue<int>q; 
    	q.push(s); d[s]=1;
    	while(q.size()){
    		int u=q.front(); q.pop();
    		for(int i=head[u];i;i=nxt[i]){
    			int v=go[i];
    			if(edge[i]&&!d[v]){
    				d[v]=d[u]+1;
    				q.push(v);
    				if(v==t)return 1;	
    			}
    		}
    	}
    	return 0;
    }
    
    int dinic(int u,int flow){
    	if(u==t)return flow;
    	int rest=flow;
    	for(int i=head[u];i&&rest;i=nxt[i]){
    		int v=go[i];
    		if(edge[i]&&d[v]==d[u]+1){
    			int k=dinic(v,min(rest,edge[i]));
    			if(!k)d[v]=-1;
    			edge[i]-=k;
    			edge[i^1]+=k;
    			rest-=k;
    		}
    	}
    	return flow-rest;
    }
    
    signed main(){
    	int ans=0;
    	n=read();
    	s=0,t=5*n+1;
    	for(int i=1,x;i<=n;i++){
    		x=read();
    		ans+=x;
    		add(s,i,x);
    	}
    	for(int i=1,x;i<=n;i++){
    		x=read();
    		ans+=x;
    		add(i,t,x);
    	}
    	m=read();
    	for(int i=1,x,y,c1,c2;i<=m;i++){
    		x=read(),c1=read(),c2=read();
    		ans+=c1+c2;
    		add(s,n+i,c1);
    		add(m+n+i,t,c2);
    		while(x--){
    			y=read();
    			add(n+i,y,inf);
    			add(y,n+m+i,inf);
    		}
    	}
    	
    	int flow=0;
    	while(bfs())
    	while(flow=dinic(s,inf))maxflow+=flow;
    	cout<<ans-maxflow<<endl;
    }
    
  • 相关阅读:
    JVM学习笔记:JVM的体系结构与JVM的生命周期
    Web 2.0 浏览器端可靠性测试第1部分(浏览器端可靠性测试的概念和背景)
    Web 2.0 浏览器端可靠性测试第2部分(如何发现和分析 Web 2.0 浏览器端的内存泄漏)
    测试人员容易遗漏的隐藏缺陷
    软件测试缺陷登记划分
    浅谈网站性能测试
    测试工程师能力胜任模型
    常见的几种web攻击方式
    软件测试分类
    app常见测试点
  • 原文地址:https://www.cnblogs.com/naruto-mzx/p/12984449.html
Copyright © 2011-2022 走看看