bzoj3438: 小M的作物
Posted ssfdjr
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj3438: 小M的作物相关的知识,希望对你有一定的参考价值。
bzoj3438: 小M的作物
妈耶好久没更新博文了。。。博客要弃了。。。ssfd
这个鬼畜的连边。。。
每个作物建一个点,S向作物连边,权值为a,作物向T连边,权值为b,割a就是选b,割b选a
然后分组这个咋搞???
你看你连好边是这样的
现在拿一组1,2,3出来
现在知道如果全选a会有c1的收益,全选b会有c2的收益
那么全选a=全割b,整个图右边都没有边了
那么新建一个点P,向123号点建流量为inf的边(没有标就是inf),只有这种情况不会割掉w
所以这个w可以是c1
c2同理
然后可以建出一个这样的图
excited
#include<bits/stdc++.h>
#define il inline
#define vd void
typedef long long ll;
il int gi(){
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return x*f;
}
#define inf 10000000000000ll
const int maxn=3333,maxm=3e6,S=maxn-1,T=maxn-2;
int fir[maxn],head[maxn],dis[maxm],nxt[maxm],id=1,dep[maxn];
ll w[maxm];
il vd link(int a,int b,ll c){
nxt[++id]=fir[a],fir[a]=id,dis[id]=b,w[id]=c;
nxt[++id]=fir[b],fir[b]=id,dis[id]=a,w[id]=0;
}
il bool BFS(){
static int que[maxn],hd,tl;
hd=tl=0;
que[tl++]=S;
for(int i=1;i<=T;++i)dep[i]=0;dep[S]=1;
while(hd^tl){
int x=que[hd];
for(int i=fir[x];i;i=nxt[i]){
if(!dep[dis[i]]&&w[i]){
dep[dis[i]]=dep[x]+1;
que[tl++]=dis[i];
}
}
++hd;
}
return dep[T];
}
il int Dinic(int x,ll maxflow){
if(x==T)return maxflow;
ll ret=0;
for(int&i=head[x];i;i=nxt[i])
if(w[i]&&dep[dis[i]]==dep[x]+1){
int d=Dinic(dis[i],std::min(maxflow-ret,w[i]));
w[i]-=d,w[i^1]+=d,ret+=d;
if(ret==maxflow)break;
}
return ret;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("3438.in","r",stdin);
freopen("3438.out","w",stdout);
#endif
int n=gi(),x;ll ans=0;
for(int i=1;i<=n;++i)link(S,i,x=gi()),ans+=x;
for(int i=1;i<=n;++i)link(i,T,x=gi()),ans+=x;
int m=gi();
for(int i=1;i<=m;++i){
int k=gi();
link(S,i+n,x=gi()),ans+=x;
link(i+n+m,T,x=gi()),ans+=x;
while(k--){
x=gi();
link(i+n,x,inf);
link(x,i+n+m,inf);
}
}
while(BFS())memcpy(head,fir,sizeof fir),ans-=Dinic(S,inf);
printf("%lld
",ans);
return 0;
}
以上是关于bzoj3438: 小M的作物的主要内容,如果未能解决你的问题,请参考以下文章