标签:
总共有m个机器,n个任务,每个任务具有
Si ,Ei ,Pi ,三种属性,从Si 到Ei ,总共需要Pi 天去完成,每个机器同一时间只能运行一个任务,任务运行时可以被中断去完成其他任务。现在问是否有一种调度方法,使这n个任务能全部完成。
这一题是网络流的题目,难点在于如何建图。
因为每个任务都可以在Si 到Ei 内任何一个时间运行,我们想到从每个任务向这些可行的时间点建边,又因为每个任务需要运行Pi 天,所以我们建立一个源点,向每个任务建立一条长度为Pi 的边。每个时间点都可能有任务停止或完成,所以我们从每个时间点向汇点建立一条长度为m的边。
这样,建好图之后我们跑一边DINIC就可以了(本题EK会TLE)
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
using namespace std;
int p[505],s[505],e[505],T,n,pre[1005],m,mint,maxt,dis[1005],num,ma[1005][1005];
bool flag[1005];
struct edge
{
int u,v,d,next;
};
edge E[600010];
bool bfs(int st,int des)
{
int q[1005],h=0,t=0;
memset(q,0,sizeof(q));
memset(dis,0,sizeof(dis));
q[h++]=st; dis[st]=1;
while (t!=h)
{
int u=q[t++];
for (int i=pre[u];i!=0;i=E[i].next)
{
int v=E[i].v;
if (!dis[v] && E[i].d)
{
dis[v]=dis[u]+1;
q[h++]=v;
if (v==des) return 1;
}
}
}
return 0;
}
int Dinic(int u,int des,int flow)
{
int ans=0;
if (u==des) return flow;
for (int i=pre[u];i!=0;i=E[i].next)
{
int v=E[i].v;
if (E[i].d && dis[v]==dis[u]+1 )
{
ans=Dinic(v,des,min(flow,E[i].d));
if (ans)
{
E[i].d-=ans;
if (ma[v][u]) E[ma[v][u]].d+=ans;
else
{
E[num].u=v;
E[num].v=u;
E[num].d=ans;
E[num].next=pre[v];
pre[v]=num;
ma[v][u]=num;
num++;
}
return ans;
}
else dis[v]=0;
}
}
return 0;
}
int main()
{
int Case=1;
scanf("%d",&T);
while(T--)
{
int sum=0; num=1; maxt=0; mint=0x7fffffff;
memset(s,0,sizeof(s));
memset(p,0,sizeof(p));
memset(e,0,sizeof(e));
memset(ma,0,sizeof(ma));
memset(pre,0,sizeof(pre));
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++)
{
scanf("%d%d%d",&p[i],&s[i],&e[i]);
mint=min(mint,s[i]);
maxt=max(maxt,e[i]);
sum+=p[i];
}
maxt=maxt-mint+1;
while (num<=n)
{
E[num].u=0;
E[num].v=num;
E[num].d=p[num];
E[num].next=pre[0];
pre[0]=num;
ma[0][num]=num;
num++;
}
for (int i=1;i<=n;i++)
for (int j=s[i]+n;j<=e[i]+n;j++)
{
E[num].u=i;
E[num].v=j;
E[num].d=1;
E[num].next=pre[i];
pre[i]=num;
ma[i][j]=num;
num++;
}
for (int i=n+1;i<=maxt+n;i++)
{
E[num].u=i;
E[num].v=n+maxt+1;
E[num].d=m;
E[num].next=pre[i];
pre[i]=num;
ma[i][n+maxt+1]=num;
num++;
}
int ans=0,t;
while (bfs(0,n+maxt+1))
{
while (t=Dinic(0,n+maxt+1,0x7fffffff)) ans+=t;
}
printf("Case %d: ",Case++);
if (ans==sum) printf("Yes\n");
else printf("No\n");
printf("\n");
}
return 0;
}
标签:
原文地址:http://blog.csdn.net/s_black/article/details/51355823