Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 6384 | Accepted: 2607 |
Description
Input
Output
Sample Input
2 2 0 1 0 1 0 1 0 9 3 0 1 1 1 0 0 0 6 4 2 0 1 0 1 0 1 0 9 4 0 1 1 1 0 0 0 6 2
Sample Output
Yes No
Hint
A proper schedule for the first test case: date Sun Mon Tue Wed Thu Fri Sat week1 film1 film2 film1 film1 week2 film1 film2 film1 film1 week3 film1 film2 film1 film1 week4 film2 film2 film2
题意:
有一个小女孩从小就梦想成为一名影星,现在机会来了,有很多电影公司找她拍电影,但是这些拍电影的日程安排之间可能还有冲突,但是有女孩不想错过任何机会,想把每个公司的电影都接下来,但是她不知道能不能接下所有的电影,所有找到了你优秀的ACMER来帮忙解决问题。
数据的输入如下:有T组数据每组先有一个N表示要找她拍的电影的个数,其中N<=20;
每个电影有9个数据,前7个数据表示一个星期的7天 ,这7个数不是0,就是1,1表示能在这天拍电影,0表示不能在这天拍电影 还有2个数据D,W。D表示这部电影需要她拍D天才能完成,W表示这D天必须在前W周内。
解析:
标准的最大流问题,就是建图稍微麻烦了一点,由题意可知,最多20部电影, 50周。50周按天算,一共350天。先把节点划分一下,节点1~20表示电影,节点21~370表示50周的每一天日期。0为源点, 371为汇点。
(1)源点到每部电影建边,权值为每部电影花费的时间。
(2)每部电影到可以拍摄的日期建边,权值为1。(这里要注意,要把前w个周可以拍摄的日期都会对应的电影连起来)
(3)所有日期到汇点建边,权值为1
跑一遍最大流,看看是否满流,满流的的话就输出Yes,否则就输出No。
</pre><pre name="code" class="cpp">#include <cstdio> #include <cstring> #include <algorithm> #include <queue> #define maxn 1000 #define maxm 20000 #define INF 0x3f3f3f3f using namespace std; int n;//n个电影 struct node{ int u, v, cap, flow, next; }; node edge[maxm]; int head[maxn], cnt, cur[maxn]; int vis[maxn], dist[maxn]; int str[25][10];//记录每部电影可以在哪一天拍摄 int sum;//总共的拍摄时间 void init(){ cnt = 0; memset(head, -1, sizeof(head)); } void add(int u, int v, int w){ node E; edge[cnt] = {u, v, w, 0, head[u]}; head[u] = cnt++; edge[cnt] = {v, u, 0, 0 ,head[v]}; head[v] = cnt++; } void getmap(){ //0为源点,371为汇点 sum = 0; scanf("%d", &n); for(int i = 1; i <= n; ++i){ for(int j = 1; j <= 7; ++j) scanf("%d", &str[i][j]); int d, w; scanf("%d%d", &d, &w); sum += d; add(0, i, d); for(int j = 1; j <= 7; ++j) for(int k = 0; k < w; ++k){//这里要注意 if(str[i][j]) add(i, 20 + k * 7 + j, 1); } } for(int i = 21; i <= 370; ++i) add(i, 371, 1); } bool BFS(int st ,int ed){ queue<int>q; memset(vis, 0 ,sizeof(vis)); memset(dist, -1, sizeof(dist)); vis[st] = 1; dist[st] = 0; q.push(st); while(!q.empty()){ int u = q.front(); q.pop(); for(int i = head[u]; i != -1; i = edge[i].next){ node E = edge[i]; if(!vis[E.v] && E.cap > E.flow){ vis[E.v] = 1; dist[E.v] = dist[u] + 1; if(E.v == ed) return true; q.push(E.v); } } } return false; } int DFS(int x, int ed, int a){ if(x == ed || a == 0) return a; int flow = 0, f; for(int &i = cur[x]; i != -1; i = edge[i].next){ node &E = edge[i]; if(dist[E.v] == dist[x] + 1 && (f = DFS(E.v, ed, min(a, E.cap - E.flow))) > 0){ E.flow += f; edge[i ^ 1].flow -= f; a -= f; flow += f; if(a == 0) break; } } return flow; } int maxflow(int st, int ed){ int flowsum = 0; while(BFS(st,ed)){ memcpy(cur, head, sizeof(head)); flowsum += DFS(st, ed, INF); } return flowsum; } int main (){ int T; scanf("%d", &T); while(T--){ init(); getmap(); int ans = maxflow(0, 371); if(ans == sum) printf("Yes\n"); else printf("No\n"); } return 0; }