zoukankan      html  css  js  c++  java
  • [CF331E] Biologist

    题目大意

    有一个长度为 (n) 的 01 串,将第 (i) 个位置变为另外一个数字的代价是(v_i) 。 有 (m) 个要求 每个要求的形式是 首先确定若干位置都要是 (0) 或者 (1)
    然后给定这 (k) 个位置,如果些位置上都满足要求 那么就可以得到 (W_k)​ 元 某些要求如果失败了还要倒着给(g) 元。问最终能够得到的最大利润

    输入格式: 第一行是 (n,m,g)
    第二行是初始的 01 串 第三行是 (V_i)
    接下来 (m) 行 第一个数字表示这个集合都要是 0 还是 1
    第二个数字 (W_i) ​ 表示利润,接下来 (k_i)​ 表示这个集合中有 (k) 个位置 接下来是这 (k) 个位置, 最后还有一个 0/1 ,如果是 1 ,表示如果失败了还要倒着给 (g) 元。

    解析

    一道非常满足最小割模型的题目。对于每个点,如果最开始是0,我们从原点向它连边,边权为(v_i),表示这个点不为0的代价。同理,对于一个为1的点,将它向汇点连边,边权为(v_i),表示该点不为1的代价。

    对于每一组要求,如果是要全为0,就从原点向这个要求对应的点连边,边权为这个要求不满足的代价(包括(w_i)以及是否有额外代价)。然后从要求对应的边向要求中的点连边,边权为无穷大。如果要求全为1,就从这个要求对应的点向汇点连边,边权为这个要求不满足的代价。然后从要求中的点向这个点连边,边权无穷大。用总代价减去最小割即为答案。

    代码

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <queue>
    #define N 20002
    #define M 2000002
    using namespace std;
    const int inf=1<<30;
    int head[N],ver[M],nxt[M],cap[M],l;
    int n,m,g,s,t,i,j,a[N],v[N],dis[N],ans;
    int read()
    {
    	char c=getchar();
    	int w=0;
    	while(c<'0'||c>'9') c=getchar();
    	while(c<='9'&&c>='0'){
    		w=w*10+c-'0';
    		c=getchar();
    	}
    	return w;
    }
    void insert(int x,int y,int z)
    {
    	ver[l]=y;
    	cap[l]=z;
    	nxt[l]=head[x];
    	head[x]=l;
    	l++;
    	ver[l]=x;
    	nxt[l]=head[y];
    	head[y]=l;
    	l++;
    }
    bool bfs()
    {
    	queue<int> q;
    	memset(dis,-1,sizeof(dis));
    	q.push(s);
    	dis[s]=0;
    	while(!q.empty()){
    		int x=q.front();
    		q.pop();
    		for(int i=head[x];i!=-1;i=nxt[i]){
    			int y=ver[i];
    			if(dis[y]==-1&&cap[i]>0){
    				dis[y]=dis[x]+1;
    				q.push(y);
    			}
    		}
    	}
    	return (dis[t]>0);
    }
    int dfs(int x,int flow)
    {
    	if(x==t||flow==0) return flow;
    	int ans=0;
    	for(int i=head[x];i!=-1;i=nxt[i]){
    		int y=ver[i];
    		if(dis[y]==dis[x]+1&&cap[i]>0){
    			int a=dfs(y,min(flow,cap[i]));
    			ans+=a;
    			flow-=a;
    			cap[i]-=a;
    			cap[i^1]+=a;
    		}
    		if(flow==0) break;
    	}
    	if(flow) dis[x]=-1;
    	return ans;
    }
    int Dinic()
    {
    	int ans=0;
    	while(bfs()) ans+=dfs(s,inf);
    	return ans;
    }
    int main()
    {
    	memset(head,-1,sizeof(head));
    	n=read();m=read();g=read();
    	t=n+m+1;
    	for(i=1;i<=n;i++) a[i]=read();
    	for(i=1;i<=n;i++) v[i]=read();
    	for(i=1;i<=n;i++){
    		if(a[i]==0) insert(s,i,v[i]);
    		else insert(i,t,v[i]);
    	}
    	for(i=1;i<=m;i++){
    		int op=read(),w=read(),k=read();
    		if(op==0){
    			for(j=1;j<=k;j++){
    				int x=read();
    				insert(n+i,x,inf);
    			}
    			int flag=read();
    			if(flag) insert(s,n+i,w+g);
    			else insert(s,n+i,w);
    			ans+=w;
    		}
    		else{
    			for(j=1;j<=k;j++){
    				int x=read();
    				insert(x,n+i,inf);
    			}
    			int flag=read();
    			if(flag) insert(n+i,t,w+g);
    			else insert(n+i,t,w);
    			ans+=w;
    		}
    	}
    	printf("%d
    ",ans-Dinic());
    	return 0;
    }
    
  • 相关阅读:
    sort uniq 命令 企业应用场景实战排序
    网络管理相关命令常用必回基础实战
    Zabbix 3.0入门到企业实战(自带模板介绍)
    jsp页面指令
    jsp九大内置对象
    如何将静态页面转化为动态页面
    转发与重定向区别
    cookie的保存时间
    登陆界面 实现思路
    卸载了mysql之后,mysql服务仍在,显示读取描述失败,错误代码2
  • 原文地址:https://www.cnblogs.com/LSlzf/p/12234812.html
Copyright © 2011-2022 走看看