bzoj 4177 Mike的农场

  • 思维有些江化了,一上来就想费用流做法,但其实就是个最小割啊.
  • 考虑先将所有的收益拿到,再减去不能拿的以及三元组 \((i,j,k)\) 产生的代价.即,先让 \(ans=\sum a_i+b_i+\sum_{(S,a,b)} b\).
  • 然后要让减去的最小,尝试构造一个最小割模型.建一个源点 \(S\) ,一个汇点 \(T\) .
  • 为了满足每个点只能选一种动物,从 \(S\) 向每个点 \(i\) 连权值为 \(a_i\) 的边,从每个点 \(i\) 向 \(T\) 连权值为 \(b_i\) 的边.
  • 为了处理三元组 \((i,j,k)\) ,对每个这样的三元组,在 \(i \to j,j\to i\) 都连一条权值为 \(k\) 的边.这样只要两者割的不一样,就还需要割掉中间的这条边.
  • 为了处理三元组 \((S,a,b)\) ,新建一个点 \(np\) ,若 \(a=0\) , 就从 \(S\) 向 \(np\) 连一条权值为 \(b\) 的边,从 \(np\) 向 \(\forall i\in S\) 连一条权值为 \(inf\) 的边.这样要么割掉这个收益 \(b\) ,要么就全部割羊的边,即全选牛.
  • \(a=1\) 同理,从 \(np\) 向 \(T\) 连一条权值为 \(b\) 的边,从 \(\forall i\in S\) 向 \(np\) 连一条权值为 \(inf\) 的边.
  • 建出图后跑一跑最小割,用 \(ans\) 减去它即得答案.
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define inf 1e18
inline ll read()
{
ll out=0,fh=1;
char jp=getchar();
while ((jp>'9'||jp<'0')&&jp!='-')
jp=getchar();
if (jp=='-')
fh=-1,jp=getchar();
while (jp>='0'&&jp<='9')
out=out*10+jp-'0',jp=getchar();
return out*fh;
}
const int MAXN=1e6+10;
int cnt=-1,head[MAXN],nx[MAXN],to[MAXN];
ll flow[MAXN];
void addedge(int u,int v,ll Flow)
{
++cnt;
to[cnt]=v;
nx[cnt]=head[u];
flow[cnt]=Flow;
head[u]=cnt;
}
void ins(int u,int v,ll Flow)
{
addedge(u,v,Flow);
addedge(v,u,0);
}
int tot=0;
int cur[MAXN],dep[MAXN];
ll maxflow=0;
bool bfs(int S,int T)
{
for(int i=1;i<=tot;++i)
dep[i]=-1;
for(int i=1;i<=tot;++i)
cur[i]=head[i];
dep[S]=0;
queue<int> q;
q.push(S);
while(!q.empty())
{
int u=q.front();
q.pop();
for(int i=head[u];i!=-1;i=nx[i])
{
int v=to[i];
if(flow[i] && dep[v]==-1)
{
dep[v]=dep[u]+1;
q.push(v);
}
}
}
if(dep[T]==-1)
return false;
return true;
}
ll dfs(int u,int t,ll limit)
{
if(!limit || u==t)
return limit;
ll Flow=0,f;
for(int i=cur[u];i!=-1;i=nx[i])
{
cur[u]=i;
int v=to[i];
if(dep[v]==dep[u]+1 && (f=dfs(v,t,min(limit,flow[i]))))
{
Flow+=f;
limit-=f;
flow[i]-=f;
flow[i^1]+=f;
if(!limit)
break;
}
}
return Flow;
}
void Dinic(int S,int T)
{
while(bfs(S,T))
maxflow+=dfs(S,T,inf);
}
int n,m,k;
int field[MAXN];
int main()
{
freopen("work.in","r",stdin);
freopen("work.out","w",stdout);
memset(head,-1,sizeof head);
int S=++tot;
int T=++tot;
n=read(),m=read(),k=read();
ll ans=0;
for(int i=1;i<=n;++i)
{
field[i]=++tot;
ll a=read();
ins(S,field[i],a);
ans+=a;
}
for(int i=1;i<=n;++i)
{
ll b=read();
ins(field[i],T,b);
ans+=b;
}
while(m--)
{
int i=read(),j=read();
ll w=read();
ins(field[i],field[j],w);
ins(field[j],field[i],w);
}
while(k--)
{
int t=read(),a=read();
ll b=read();
ans+=b;
int np=++tot;
if(a==0)
{
ins(S,np,b);
for(int i=1;i<=t;++i)
{
int x=read();
ins(np,field[x],inf);
}
}
else
{
ins(np,T,b);
for(int i=1;i<=t;++i)
{
int x=read();
ins(field[x],np,inf);
}
}
}
Dinic(S,T);
ans-=maxflow;
cout<<ans<<endl;
return 0;
}

bzoj 4177 Mike的农场的更多相关文章

  1. BZOJ 4177: Mike的农场( 最小割 )

    显然是最小割... 对于规律(i, j, k) i,j 互相连边, 容量为k 对于规则(S, a, b) 新建一个点x, x与S中每个点连一条弧, 容量+∞, 然后再根据a决定x与源点或汇点连边. 跑 ...

  2. bzoj4177: Mike的农场

    类似于最大权闭合图的思想. #include<cstdio> #include<cstring> #include<iostream> #include<al ...

  3. 【BZOJ4177】Mike的农场 最小割

    [BZOJ4177]Mike的农场 Description Mike有一个农场,这个农场n个牲畜围栏,现在他想在每个牲畜围栏中养一只动物,每只动物可以是牛或羊,并且每个牲畜围栏中的饲养条件都不同,其中 ...

  4. Mike的农场 (BZOJ 4177)

    题目大意: 给N个东西分AB类,分到A类和B类分别得到相应的钱记为A[i],B[i],然后有一些冲突关系<x,y,z>,如果物品x,y不同类需要付出z的钱.还有一些外快<S,x,y& ...

  5. 【bzoj4177】Mike的农场 网络流最小割

    题目描述 Mike有一个农场,这个农场n个牲畜围栏,现在他想在每个牲畜围栏中养一只动物,每只动物可以是牛或羊,并且每个牲畜围栏中的饲养条件都不同,其中第i个牲畜围栏中的动物长大后,每只牛可以卖a[i] ...

  6. Mike的农场

    题目 Mike有一个农场,这个农场n个牲畜围栏,现在他想在每个牲畜围栏中养一只动物,每只动物可以是牛或羊,并且每个牲畜围栏中的饲养条件都不同,其中第i个牲畜围栏中的动物长大后,每只牛可以卖a[i]元, ...

  7. bzoj:2018 [Usaco2009 Nov]农场技艺大赛

    Description Input 第1行:10个空格分开的整数: N, a, b, c, d, e, f, g, h, M Output 第1行:满足总重量最轻,且用度之和最大的N头奶牛的总体重模M ...

  8. Mike的农场 BZOJ4177

    分析: 最小割,不选则割的建模题...(然而一开始我当成了费用流,简直丧心病狂...最后想到了最小割...) 对于条件一,直接建一条双向边就可以了,并且不计入sum中,因为这是作为费用的存在,让它跑出 ...

  9. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

随机推荐

  1. (16)Cocos2d-x 多分辨率适配完全解析

    Overview 从Cocos2d-x 2.0.4开始,Cocos2d-x提出了自己的多分辨率支持方案,废弃了之前的retina相关设置接口,提出了design resolution概念. 3.0中有 ...

  2. [LeetCode]206. Reverse Linked List(链表反转)

    Reverse a singly linked list. click to show more hints. Subscribe to see which companies asked this ...

  3. Codeforces Round #530 (Div. 2) Solution

    A. Snowball 签. #include <bits/stdc++.h> using namespace std; ], d[]; int main() { while (scanf ...

  4. "字节跳动杯"2018中国大学生程序设计竞赛-女生专场 Solution

    A - 口算训练 题意:询问 $[L, R]$区间内 的所有数的乘积是否是D的倍数 思路:考虑分解质因数 显然,一个数$x > \sqrt{x} 的质因子只有一个$ 那么我们考虑将小于$\sqr ...

  5. bzoj1297 / P4159 [SCOI2009]迷路

    P4159 [SCOI2009]迷路 如果边权只有 0/1 那么不就是一个灰常简单的矩阵快速幂吗! 然鹅边权 $<=9$ 所以我们把每个点拆成9个点! 解决~ #include<iostr ...

  6. jQuery Mobile中的页面加载与跳转机制

    第一次做用jQuery Mobile做东西,发现一些跟平时的思维习惯不太一样的.其中这个框架的页面加载机制便是其中一个.如果不明白其中的奥秘,往往会出现一些让人摸不着头脑的怪现象,比如页面进入后点击按 ...

  7. SpringBoot与Dubbo整合下篇

    (1)pom.xml引入相关依赖jar包,如下: <dependency> <groupId>com.alibaba</groupId> <artifactI ...

  8. Tp5,Service使用

    C层,操控数据库,并处理页面数据展示. M层,纯粹的操作自己所对应的数据库. Service层,可以通用的处理一些逻辑计算,也可以将复杂的数据表处理整合到一起,也可以将复杂的业务逻辑整合到一起. 创建 ...

  9. Spring中的@Transactional

    spring中的@Transactional基于动态代理的机制,提供了一种透明的事务管理机制,方便快捷解决在开发中碰到的问题. 一般使用是通过如下代码对方法或接口或类注释: @Transactiona ...

  10. 51nod1284容斥定理

    1284 2 3 5 7的倍数 基准时间限制:1 秒 空间限制:131072 KB 分值: 5 难度:1级算法题   给出一个数N,求1至N中,有多少个数不是2 3 5 7的倍数. 例如N = 10, ...