思路:
一道比较好的最大流题目,与常规方法:将点划分每个单位时间点所对应的状态点有所不同,这里采用了时间段的思想,记录所有客人需求的时间点,进行去重,这样就有了一个个时间段
这里利用时间段的思想,避免了高达1e6的时间范围下的按单位时间的复杂建图情况,并且考虑到可以将每个顾客的需求量拆分成单位长度,因此可以直接将超级源点与人之间的容量设置为总烧烤时间
建图模式:
超级源点->人->时间段->超级汇点
超级源点->人:总烧烤时间
人->时间段:INF
时间段->超级汇点:时间长度*机器数
代码如下:
#pragma GCC optimize(2)
#include<cstdio>
#include<string>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#include<list>
#include<map>
#include<set>
#include<cmath>
#include<cstring>
#include<iostream>
#define _PI acos(-1.0)
#define esp 1e-9
#define IOS ios::sync_with_stdio(0);cin.tie(0);
#define FRE freopen("abc.in", "r", stdin)
#define mEm(X,Y) memset(X,Y,sizeof(X))
#define pb(a) push_back(a)
#define pa(a) pop_back(a)
#define rep(i,a,b) for(int i=a;i<b;++i)
#define rep1(i,a,b) for(int i=a;i<=b;++i)
#define INF 0x3f3f3f3f
typedef long long LL;
typedef unsigned long long ULL;
LL gcd(LL a, LL b) { return b ? gcd(b, a % b) : a; }
void exgcd(LL a, LL b, LL& x, LL& y) {
if (!b) {
x = 1, y = 0;
return;
}
exgcd(a, b, y, x);
y -= a / b * x;
}
using namespace std;
/*===========================================*/
//使用非vector链式前向星
class MAXFLOW
{
public:
static const int MAXN = 100200;
struct Edge
{
int v, flow, next;
} e[MAXN << 2];
int head[MAXN], edge_num, layer[MAXN], start, end;
void reload()
{
edge_num = 0;
memset(head, -1, sizeof(head));
}
void addedge(int u, int v, int w)
{
e[edge_num].v = v;
e[edge_num].flow = w;
e[edge_num].next = head[u];
head[u] = edge_num++;
e[edge_num].v = u;
e[edge_num].flow = 0;
e[edge_num].next = head[v];
head[v] = edge_num++;
}
bool bfs()
{
queue<int> Q;
Q.push(start);
memset(layer, 0, sizeof(layer));
layer[start] = 1;
while (Q.size())
{
int u = Q.front();
Q.pop();
if (u == end)
return true;
for (int j = head[u]; j != -1; j = e[j].next)
{
int v = e[j].v;
if (layer[v] == false && e[j].flow)
{
layer[v] = layer[u] + 1;
Q.push(v);
}
}
}
return false;
}
int dfs(int u, int MaxFlow, int End)
{
if (u == End)
return MaxFlow;
int uflow = 0;
for (int j = head[u]; j != -1; j = e[j].next)
{
int v = e[j].v;
if (layer[v] - 1 == layer[u] && e[j].flow)
{
int flow = min(MaxFlow - uflow, e[j].flow);
flow = dfs(v, flow, End);
e[j].flow -= flow;
e[j ^ 1].flow += flow;
uflow += flow;
if (uflow == MaxFlow)
break;
}
}
if (uflow == 0)
layer[u] = 0;
return uflow;
}
int dinic()
{
int MaxFlow = 0;
while (bfs())
MaxFlow += dfs(start, 0x3f3f3f3f, end);
return MaxFlow;
}
}sol;
vector<int> s, e;
vector<int> time;
int main()
{
int n, m;
while (~scanf("%d%d", &n, &m))
{
time.clear(), s.clear(), e.clear();
int a, b, c, d;
sol.reload();
int tot = 0;
rep1(i, 1, n)
{
scanf("%d%d%d%d", &a, &b, &c, &d);
s.push_back(a), e.push_back(c), time.push_back(a), time.push_back(c);
sol.addedge(0, i, b * d);
tot += b * d;
}
sort(time.begin(), time.end());
time.erase(unique(time.begin(), time.end()), time.end());
sol.start = 0, sol.end = n + time.size();
rep(i, 1, time.size())
{
sol.addedge(n + i, sol.end, m * (time[i] - time[i - 1]));
rep(j, 0, n)
{
if (time[i - 1] >= s[j] && time[i] <= e[j])
sol.addedge(j + 1, n + i, INF);
}
}
printf("%s\n", sol.dinic() == tot ? "Yes" : "No");
}
}