P2763 试题库问题 最大流

原题:https://www.luogu.org/problemnew/show/P2763

题解:其实就是就是n个试题和k配对。建图方法: S连i(i∈n), j连T(j∈k),且边的流量是a[i]。如题连i->j就行了。跑一边最大流,从k枚举,输出答案。然而洛谷上要英文冒号。

#include<bits/stdc++.h>
#define inf 0x7fffffff
using namespace std;
const int N=2200;
const int M=220000;
struct E{int to,w,nxt;}data[M<<1];
int len,n,k,S,T,sum;
int h[N],dep[N],cur[N];
queue<int> q;
inline int rd(){
	int x=0;int f=1;char s=getchar();
	while(!isdigit(s)) f=(s=='-'?-1:f),s=getchar();
	while(isdigit(s)) x=(x<<1)+(x<<3)+s-'0',s=getchar();
	return x*f;
}
inline void ins(int x,int y,int w){
	data[++len].to=y;data[len].w=w;data[len].nxt=h[x];h[x]=len;
	data[++len].to=x;data[len].w=0;data[len].nxt=h[y];h[y]=len; 
}
bool bfs(){
	memset(dep,0,sizeof dep);
	dep[S]=1;q.push(S);
	while(!q.empty()){
		int x=q.front();q.pop();
		for(int i=h[x];i;i=data[i].nxt){
			int y=data[i].to;int w=data[i].w;
			if(!dep[y] && w!=0){
				dep[y]=dep[x]+1;q.push(y); 
			}		
		}
	}
	return dep[T];
} 
int dfs(int x,int lim){
	if(x==T) return lim;
	for(int &i=cur[x];i;i=data[i].nxt){
		int y=data[i].to;int w=data[i].w;
		if(dep[y]==dep[x]+1 && w!=0){
			int di=dfs(y,min(lim,w));
			if(di){
				data[i^1].w+=di;
				data[i].w-=di;
				return di;
			}
		}
	}
	return 0;
}
inline int dinic(){
	int ans=0;
	while(bfs()){
		for(int i=S;i<=T;i++) cur[i]=h[i];
		while(int k=dfs(S,inf)) ans+=k;
	} 
	return ans;
}



int main(){
//	freopen("testdata.in","r",stdin);
	k=rd();n=rd();len=1;S=0;T=n+k+1;sum=0;
	for(int i=1,x;i<=k;i++) x=rd(),ins(i+n,T,x),sum+=x;
	for(int i=1,x;i<=n;i++) {
		int cnt=rd();ins(S,i,1);
		while(cnt--) x=rd(),ins(i,x+n,1);
	}
	int ans=dinic();
	if(sum!=ans){printf("No Solution!\n");return 0;}
	
	for(int x=1;x<=k;x++){
		printf("%d: ",x);
		for(int i=h[x+n];i;i=data[i].nxt){
			int y=data[i].to;int w=data[i].w;  
			if(w && y!=T) printf("%d ",y);
		}
		printf("\n");
	}
	return 0;
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值