【网络流24题】太空飞行计划问题

(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;
}
原文地址:https://www.cnblogs.com/LLCSBlog/p/11258057.html