Gym - 101170J[最大流]

版权声明:欢迎随便转载。 https://blog.csdn.net/a1214034447/article/details/89792603

题目链接:https://vjudge.net/contest/298079#problem/J

解题思路:

将整个过程分成n个步骤,那么在每个步骤中都有一个新的队列,它是空的,现在要加入当前步骤的a[i],但是还有考虑上一个步骤是否队列中还存在数据没有被传送,所以我们需要从上一个步骤连一条边指向下一个步骤,把它加到a[i]中一起处理。还有每一个步骤都有一个d可以将数据流出,所以我们一个可以分割成n*(s+q) + n个点,然后去跑最大流。

#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int dx[4] = {1,0,0,-1};
const int dy[4] = {0,1,-1,0};
const int mx = 1e4 + 10;
int n,m,S,T,tot,head[mx],cur[mx],s;
int du[mx],c[mx];
int a[mx],q;
bool vis[mx];
struct node
{
	int v,f;
	int nxt;
}e[mx*10];
void add(int u,int v,int f)
{
	e[tot] = {v,f,head[u]};
	head[u] = tot++;
	e[tot] = {u,0,head[v]};
	head[v] = tot++;
}
int dep[mx];
bool bfs()
{
	memset(dep,0,sizeof(dep));
	queue<int> que;
	que.push(S);
	dep[S] = 1;
	while(!que.empty())
	{
		int no = que.front();
		que.pop();
		for(int i=head[no];~i;i=e[i].nxt)
		{
			int v = e[i].v;
			if(e[i].f&&!dep[v]){
				dep[v] = dep[no] + 1;
				que.push(v);
			}
		}
	}
	return dep[T];
}
int dfs(int u,int flow)
{
	if(u==T || !flow) return flow;
	int used = 0;
	for(int i=head[u];~i;i=e[i].nxt)
	{
		int v = e[i].v;
		if(dep[u]+1==dep[v]){
			int w = dfs(v,min(flow-used,e[i].f));
			e[i].f -= w;
			e[i^1].f += w;
			used += w;
			if(used==flow) return flow;
		}
	}
	if(!used) dep[u] = 0;
	return used;
}
int maxflow()
{
	int ans = 0;
	while(bfs()){
	//	copy(head,head+mx,cur);
		ans += dfs(S,inf);
	}
	return ans;
}
int getid(int i,int j,int w)
{
	if(w) return i*(s+q) + s + j;
	return i*(s+q) + j;
}
int main()
{
	scanf("%d%d%d",&n,&q,&s);
	int v,cnt = n*(s+q),d;
	ll sum = 0;
	for(int i=1;i<=s;i++){
		scanf("%d",du+i);
	}
	memset(head,-1,sizeof(head));
	S = 0,T = cnt + n + 1;
	for(int i=1;i<=q;i++) scanf("%d",c+i);
	for(int i=0;i<n;i++){
		scanf("%d",&d);
		for(int j=1;j<=q;j++) vis[j] = 0;
		for(int j=1;j<=s;j++){
			scanf("%d",&v);
			sum += v;
			int ids = getid(i,j,0);
			int idq = getid(i,du[j],1);
			add(S,ids,v);
			add(ids,idq,inf);
			if(!vis[du[j]]){
				add(idq,cnt+i+1,c[du[j]]);
				if(i!=n-1) add(cnt+i+1,getid(i+1,j,0),inf);
				vis[du[j]] = 1;
			}
		} 
		add(cnt+i+1,T,d);
	}
	if(sum==maxflow()) puts("possible");
	else puts("impossible");
	return 0;
}

猜你喜欢

转载自blog.csdn.net/a1214034447/article/details/89792603