\(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=='\r')getchar(),endflag=1;if(ch=='\n')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;
}