洛谷 P2763 試題庫問題 (網絡流24題)

題目:試題庫問題

思路:
源點S向所有試題連邊,邊權爲1。
所有試題向對應的類型連邊,權爲1。
所有類型向匯點T連邊,權爲需要的試題數量。
跑最大流並輸出路徑即可。

代碼:

#include<bits/stdc++.h>
using namespace std;

#define maxk 20
#define maxn 1000
#define maxm 100000
#define inf ((int)1e9)
#define read(x) scanf("%d",&x)

struct Edge{
	int u,v,w;
	Edge(){}
	Edge(int uu,int vv,int ww) {u=uu,v=vv,w=ww;}
};

int K,n,m;

Edge e[maxm+5];
int h[maxm+5],nxt[maxm+5],cnt=-1;

int d[maxm+5],cur[maxn+5];

void addedge(int u,int v,int w) {
	e[++cnt]=Edge(u,v,w);
	nxt[cnt]=h[u];
	h[u]=cnt;
}

void readin() {
	memset(h,-1,sizeof(h));
	memset(nxt,-1,sizeof(nxt));
	
	read(K),read(n);
	for(int i=1;i<=K;i++) {
		int x;read(x);m+=x;
		addedge(i,n+K+1,x);
		addedge(n+K+1,i,0);
	}
	
	for(int i=1;i<=n;i++) {
		int x;read(x);
		addedge(0,i+K,1),addedge(i+K,0,0);
		for(int j=1;j<=x;j++) {
			int y;read(y);
			addedge(i+K,y,1);addedge(y,i+K,0);
		}
	}
}

queue<int> que;

bool bfs() {
	memset(d,0,sizeof(d));
	d[0]=1;que.push(0);
	while(!que.empty()) {
		int x=que.front();que.pop();
		for(int i=h[x];~i;i=nxt[i]) {
			Edge y=e[i];
			if(d[y.v]||!y.w) continue;
			d[y.v]=d[x]+1;
			que.push(y.v);
		}
	}
	if(d[n+K+1]) return true;
	return false;
}
 
int dfs(int x,int w) {
	if(x==n+K+1) return w;
	for(int& i=cur[x];~i;i=nxt[i]) {
		Edge y=e[i];
		if(d[y.v]-d[x]!=1||!y.w) continue;
		int z=dfs(y.v,min(w,y.w));
		if(z) {
			e[i].w-=z;
			e[i^1].w+=z;
			return z;
		}
	}
	return 0;
}

int dinic() {
	int ans=0;
	while(bfs()) {
		for(int i=0;i<=n+K+1;i++) cur[i]=h[i];
		while(int x=dfs(0,inf)) ans+=x;
	}
	return ans;
}

vector<int> a[maxn+5];

void print() {
	for(int i=0;i<=cnt;i++) if(e[i].w&&e[i].u>0&&e[i].u<=K&&e[i].v>K&&e[i].v<n+K+1) a[e[i].u].push_back(e[i].v-K);
	for(int i=1;i<=K;i++) {
		printf("%d:",i);
		for(int j=0;j<a[i].size();j++) printf(" %d",a[i][j]);
		printf("\n");
	}
}

int main() {
	readin();
	int ans=dinic();
	if(ans!=m) printf("No Solution!");
	else print();
	
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章