(Problem:)(Link)
最大权闭合子图裸题。
有时间我可能会写一篇博客总结一下最大权闭合子图问题。(咕
最大权闭合子图模型:实验为正权点,仪器为负权点,实验向仪器连边。
求最大权闭合子图。
一看:啊,板子题。
不过这题还要输出方案。
这个很简单,最后得到的最大权闭合子图一定是网络流图中不在割集中的点。
割集实际上就是(dinic)最后一次分层时流量跑满的点,则它的dep是一定没有赋值的。
扫一遍就可以了。
不知道为什么容易RE,数组一怒开了1000,A了。。。
/*
@Date : 2019-07-28 08:32:30
@Author : Adscn (adscn@qq.com)
@Link : https://www.cnblogs.com/LLCSBlog
*/
#include<bits/stdc++.h>
using namespace std;
#define IL inline
#define RG register
#define gi getint()
#define gc getchar()
#define File(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout)
bool endflag=0;
IL int getint()
{
RG int xi=0;
RG char ch=gc;
bool f=0;
while(ch<'0'||ch>'9')ch=='-'?f=1:f,ch=gc;
while(ch>='0'&&ch<='9')xi=(xi<<1)+(xi<<3)+ch-48,ch=gc;
if(ch=='
')getchar(),endflag=1;
if(ch=='
')endflag=1;
return f?-xi:xi;
}
template<typename T>
IL void pi(T k,char ch=0)
{
if(k<0)k=-k,putchar('-');
if(k>=10)pi(k/10,0);
putchar(k%10+'0');
if(ch)putchar(ch);
}
const int N=1000+7,M=N;
const int S=0;
int T;
const int inf=INT_MAX;
struct edge{
int v,nxt,flow;
}e[M*5];
int head[N*5+7],cnt;
int cur[N*5+7];
inline void add(int u,int v,int f){e[++cnt]=(edge){v,head[u],f},head[u]=cnt;}
inline void link(int u,int v,int f){add(u,v,f),add(v,u,0);}
inline void init(void){memset(head,cnt=-1,sizeof head);}
int dep[N*5+7];
inline bool bfs(void)
{
memset(dep,0,sizeof dep);
static int Q[N*5+7];
register int l,r;
dep[Q[l=r=0]=S]=1;
while(l<=r)
{
int p=Q[l++];
for(int i=head[p],v;~i;i=e[i].nxt)
if(e[i].flow&&dep[v=e[i].v]==0)
dep[v]=dep[p]+1,Q[++r]=v;
}
return dep[T];
}
inline int dfs(int p,int restflow)
{
if(p==T||restflow==0)return restflow;
int sumflow=0;
for(register int &i=cur[p],flow;~i;i=e[i].nxt)
{
register int v=e[i].v;
if(e[i].flow&&dep[v]==dep[p]+1&&
( flow=dfs(v,min(restflow,e[i].flow)) ))
{
restflow-=flow,sumflow+=flow;
e[i].flow-=flow,e[i^1].flow+=flow;
if(!restflow)break;
}
}
return sumflow;
}
inline int dinic(void)
{
int maxflow=0;
while(bfs())
memcpy(cur,head,sizeof head),maxflow+=dfs(S,inf);
return maxflow;
}
struct research{
int val;
vector<int> p;
}re[M];
int val[N];
int m,n;
int main(void)
{
init();
m=gi,n=gi;
T=m+n+10;
int sum=0;
for(int i=1;i<=m;++i)
{
sum+=(re[i].val=gi);
link(S,i,re[i].val);
endflag=0;
do re[i].p.push_back(gi);while(!endflag);
for(auto &&j:re[i].p)link(i,j+m,inf);
}
for(int i=1;i<=n;++i)val[i]=gi,link(i+m,T,val[i]);
int maxflow=dinic();
for(int i=1;i<=m;++i)if(dep[i])pi(i,' ');puts("");
for(int i=1;i<=n;++i)if(dep[i+m])pi(i,' ');puts("");
pi(sum-maxflow);
return 0;
}