poj 1698 Alice‘s Chance

poj 1698  Alice‘s Chance 

题目地址: http://poj.org/problem?id=1698

题意: 演员Alice ,面对n场电影,每场电影拍摄持续w周,每周特定几天拍摄,每场电影需要Alice到场的天数为d。 请问Alice是否可以参与所有的电影拍摄。 

最近在学习最大流的算法。 

(1), 最大流真的是一种神奇的算法,最大的亮点是最大流的可回溯性,其可回溯性体现在反向边的提出。 

(2), 最大流的应用也是非常灵活的,其中一个体现在如何构建流量网络,本题采用逆向思维, 0 作为出发点, 1,2,... n作为电影点,出发点与电影点之间的流量是每一场电影需要Alice去拍摄的天数的,n+1, n+2, ..... 7*tw+n 这部分代表的是所有天数的点。每一部电影都连接该电影拍摄特定的天数(流量为1), 最后所有的天数(n+1, n+2, ... 7*tw+n)汇集到终点 7*tw+n+1 , 如果这个点的最大流与顾客总天数一致,说明ok。

// 1698 
#include <iostream> 
#include <cstdio> 
#include <cstdlib> 
#include <cstring> 
using namespace std; 

const int INF = 2100000000; 
const int maxn = 7*55 + 20 + 1 ; 

int n, mp[maxn][maxn], path[maxn], que[maxn*maxn]; 

int BFS(int src, int dest){
	memset(path, -1, sizeof(path)); 
	int cur, head = 0, tail = 0, minFlow = INF; 
	que[tail++] = src; 
	while(head < tail){
		cur = que[head++]; 
		if(cur == dest){
			break; 
		}
		for(int i=0; i<=dest; ++i){
			if(path[i]==-1 && mp[cur][i]){
				if(minFlow > mp[cur][i]){
					minFlow = mp[cur][i]; 
				}
				path[i] = cur; 
				que[tail++] = i; 
			}
		}
	}
	if(path[dest] == -1){
		return -1; 
	}
	return minFlow; 
}

int MaxFlow(int src, int dest){
	int cur, pre, flow, maxFlow = 0; 
	while( (flow = BFS(src, dest)) != -1){
		maxFlow += flow; 
		cur = dest; 
		while(cur != src){
			pre = path[cur]; 
			mp[pre][cur] -= flow; 
			mp[cur][pre] += flow; 
			cur = pre; 
		}
	}
	return maxFlow; 
}

int main(){
	freopen("in.txt", "r", stdin); 

	int test_num, d, w, sum, ans, tw=50, f[8]; 
	scanf("%d", &test_num); 
	while(test_num--){
		memset(mp, 0, sizeof(mp));  sum = 0; 
		scanf("%d", &n); 
		for(int j=1; j<=n; ++j){
			for(int i=1; i<=7; ++i){
				scanf("%d", &f[i]); 
			}
			scanf("%d %d", &d, &w); 
			sum += d; 
			mp[0][j] += d; 
			for(int i=1; i<=7; ++i){
				if(f[i] == 1){
					for(int k=0; k<w; ++k){
						mp[j][n + 7*k + i] += 1; 
					}
				}
			}
		}
		for(int j=n+1; j<=n+tw*7; ++j){
			mp[j][n+tw*7+1] += 1; 
		}
		ans = MaxFlow(0, n+tw*7+1); 
		if(ans == sum){
			printf("Yes
");
		}else{
			printf("No
");
		}
	}
	return 0; 
}

  

原文地址:https://www.cnblogs.com/zhang-yd/p/5949621.html