题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3572
题意:有m台机器,有n个任务,每个任务需要花费pi实现才能做完,而且第i个任务只能在规定的si到ei这个时间段才能在机器上运行,一台机器只能跑一个任务,但是你可以把一个任务跑到一半去跑另一个,问你能否每个任务的规定时间里面,把所有任务做完。
解析:这个可以理解为多源点多汇点的最大流,对于每一个时间点来说,每一个机器只能工作一个任务,所以任务和每个时间点建边,容量为1,然后加一个超级汇点和超级源点,超级源点和每一个任务建边,容量为pi,然后每个时间点和超级汇点建边,容量为m,表示每个时间点最多m台机器工作,然后求最后的最大流是否等于pi之和
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1010;
const int inf = 0x7fffffff;
struct node
{
int to,cap,rev;
node() {}
node(int _to,int _cap,int _rev)
{
to = _to;
cap = _cap;
rev = _rev;
}
};
vector<node>G[maxn];
int level[maxn],iter[maxn];
void addedge(int u,int v,int cap)
{
G[u].push_back(node(v,cap,G[v].size()));
G[v].push_back(node(u,0,G[u].size()-1));
}
bool bfs(int s,int t)
{
memset(level,-1,sizeof(level));
level[s] = 0;
queue<int>q;
q.push(s);
while(!q.empty())
{
int v = q.front();
q.pop();
for(unsigned i = 0;i<G[v].size();i++)
{
node e = G[v][i];
if(level[e.to]<0 && e.cap>0)
{
level[e.to] = level[v]+1;
q.push(e.to);
}
}
}
return level[t] != -1;
}
int dfs(int v,int t,int f)
{
if(v==t) return f;
for(int &i = iter[v];i<(int)G[v].size();i++)
{
node &e = G[v][i];
if(level[e.to]>level[v] && e.cap>0)
{
int d = dfs(e.to,t,min(e.cap,f));
if(d>0)
{
e.cap -= d;
G[e.to][e.rev].cap += d;
return d;
}
}
}
return 0;
}
int max_flow(int s,int t)
{
int flow = 0,f;
while(bfs(s,t))
{
memset(iter,0,sizeof(iter));
while((f = dfs(s,t,inf))>0)
flow += f;
}
return flow;
}
int main(void)
{
int t,case_t = 1;
scanf("%d",&t);
while(t--)
{
for(int i=0;i<maxn;i++)
G[i].clear();
int n,m;
scanf("%d %d",&n,&m);
int ma = 0,mi = inf,sum = 0;
for(int i=1;i<=n;i++)
{
int p,s,e;
scanf("%d %d %d",&p,&s,&e);
addedge(0,i,p);
sum += p;
for(int j=s;j<=e;j++)
addedge(i,j+n,1);
mi = min(s,mi);
ma = max(e,ma);
}
int e = ma+500;
for(int i=mi;i<=ma;i++)
addedge(n+i,e,m);
int ans = max_flow(0,e);
printf("Case %d: ",case_t++);
if(ans==sum)
puts("Yes\n");
else
puts("No\n");
}
return 0;
}