题目链接:点击打开链接
题目大意: 有个人想拍n部电影,每部电影限定每周哪几天可以拍
并且必须在第ki周之前把这部电影拍完,问能否拍完n部电影
解题思路: 把每部电影当作一个顶点,源点指向这些顶点,容量为该电影需要拍多少天
然后把每一天都当作顶点,某个工作可以在这天完成就连容量为1大边
每天的顶点指向汇点,容量也为1
最后求出最大流,满流则说明可以完成这些工作
啦啦啦
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
template <class T>
inline bool rd(T &ret) {
char c; int sgn;
if(c=getchar(),c==EOF) return 0;
while(c!='-'&&(c<'0'||c>'9')) c=getchar();
sgn=(c=='-')?-1:1;
ret=(c=='-')?0:(c-'0');
while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0');
ret*=sgn;
return 1;
}
template <class T>
inline void pt(T x) {
if (x <0) {
putchar('-');
x = -x;
}
if(x>9) pt(x/10);
putchar(x%10+'0');
}
using namespace std;
//点标 [0,n]
const int N = 20+50*7+100;
const int M = 500010;
const int INF = ~0u >> 2;
template<class T>
struct Max_Flow {
int n;
int Q[N], sign;
int head[N], level[N], cur[N], pre[N];
int nxt[M], pnt[M], E;
T cap[M];
void Init(int n) {
this->n = n+1;
E = 0;
std::fill(head, head + this->n, -1);
}
//有向rw 就= 0
void add(int from, int to, T c) {
pnt[E] = to;
cap[E] = c;
nxt[E] = head[from];
head[from] = E++;
pnt[E] = from;
cap[E] = 0;
nxt[E] = head[to];
head[to] = E++;
}
bool Bfs(int s, int t) {
sign = t;
std::fill(level, level + n, -1);
int *front = Q, *tail = Q;
*tail++ = t; level[t] = 0;
while(front < tail && level[s] == -1) {
int u = *front++;
for(int e = head[u]; e != -1; e = nxt[e]) {
if(cap[e ^ 1] > 0 && level[pnt[e]] < 0) {
level[pnt[e]] = level[u] + 1;
*tail ++ = pnt[e];
}
}
}
return level[s] != -1;
}
void Push(int t, T &flow) {
T mi = INF;
int p = pre[t];
for(int p = pre[t]; p != -1; p = pre[pnt[p ^ 1]]) {
mi = std::min(mi, cap[p]);
}
for(int p = pre[t]; p != -1; p = pre[pnt[p ^ 1]]) {
cap[p] -= mi;
if(!cap[p]) {
sign = pnt[p ^ 1];
}
cap[p ^ 1] += mi;
}
flow += mi;
}
void Dfs(int u, int t, T &flow) {
if(u == t) {
Push(t, flow);
return ;
}
for(int &e = cur[u]; e != -1; e = nxt[e]) {
if(cap[e] > 0 && level[u] - 1 == level[pnt[e]]) {
pre[pnt[e]] = e;
Dfs(pnt[e], t, flow);
if(level[sign] > level[u]) {
return ;
}
sign = t;
}
}
}
T Dinic(int s, int t) {
pre[s] = -1;
T flow = 0;
while(Bfs(s, t)) {
std::copy(head, head + n, cur);
Dfs(s, t, flow);
}
return flow;
}
};
Max_Flow <int>F;
int n;
void work(){
rd(n);
int from = 0, to = n + 50*7 +1;
F.Init(to);
int all = 0;
for(int i = 1, d, w; i <= n; i++)
{
int a[8];
for(int j = 1; j <= 7; j++)rd(a[j]);
rd(d); rd(w);
all += d;
F.add(from, i, d);
for(int week = 0; week < w; week++)
for(int j = 1; j <= 7; j++)
if(a[j])
F.add(i, n+week*7+j, 1);
}
for(int i = 0; i < 50; i++)
for(int j = 1; j <= 7; j++)
F.add(n+i*7+j, to, 1);
all == F.Dinic(from, to)?puts("Yes"):puts("No");
}
int main(){
int T; rd(T);
while(T--)
work();
return 0;
}