HDU--杭电--3572--Task Schedule--最大流

Task Schedule

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)

Total Submission(s): 5031    Accepted Submission(s): 1642

Problem Description

Our geometry princess XMM has stoped her study in computational geometry to concentrate on her newly opened factory. Her factory has introduced M new machines in order to process the coming N tasks. For the i-th task, the factory
has to start processing it at or after day Si, process it for Pi days, and finish the task before or at day Ei. A machine can only work on one task at a time, and each task can be processed by at most one machine at a time. However, a task can be interrupted
and processed on different machines on different days.

Now she wonders whether he has a feasible schedule to finish all the tasks in time. She turns to you for help.

Input

On the first line comes an integer T(T<=20), indicating the number of test cases.

You are given two integer N(N<=500) and M(M<=200) on the first line of each test case. Then on each of next N lines are three integers Pi, Si and Ei (1<=Pi, Si, Ei<=500), which have the meaning described in the description. It is guaranteed that in a feasible
schedule every task that can be finished will be done before or at its end day.

Output

For each test case, print “Case x: ” first, where x is the case number. If there exists a feasible schedule to finish all the tasks, print “Yes”, otherwise print “No”.

Print a blank line after each test case.

Sample Input

2
4 3
1 3 5
1 1 4
2 3 7
3 5 9

2 2
2 1 3
1 2 2

Sample Output

Case 1: Yes

Case 2: Yes

题意:给你m个机器和n个任务,每个机器一次只能运行一个任务,但是可以运行中断换任务,每个任务有一个开始的最早时间Si和完成的最晚时间Ei,这个任务完成需要的时间Pi,问是否可以完成所有任务。。

*****这个题比较难想到网络流,但是想到点上了就发现这就是个网络流,我开始用最初学的那个算法写,结果CE,不明就里,就改啊改的,然后是RE,说是下标越界,再改就成了TLE,超时。。。然后临时在网上复习了一下dinic算法,这个耗时小一些。。。

题解:和普通网络流一样,设置一个超级原点S和超级汇点T,S连接每个任务,流量限制为这个任务的Pi,T连接每个时间点,流量限制为m,因为同一时刻m个机器是能同时运行的,然后把每个任务同它相关的时间点都连接起来,流量限制为1,然后进行你的网络流模版就是了~~

#include <iostream>

#include <cstdio>

#include <cstring>

#include <queue>

#define MAX 1000000001

#define Max(a,b) a>b?a:b

#define Min(a,b) a<b?a:b

#define M 1111

using namespace std;

int n,m,sum;

struct node

{

    int to,val,next;//流向的点,流量限制,下一个对应的点

}s[M*M];//其实就类似做一个线性表

int hand[M],snum;//hand[x]表示x在之前最后出现的那次,在s中的位置,snum是s的长度

int dis[M],q[M];//dis记录dinic算法中用bfs分的层,q是模拟队列

void setit(int from,int to,int
val
)

{

s[snum].to=to;//正向,流量限制为输入的这个

s[snum].val=val;

s[snum].next=hand[from];

hand[from]=snum++;

s[snum].to=from;//反向 流量限制初始化为0

s[snum].val=0;

s[snum].next=hand[to];

hand[to]=snum++;

}

int bfs()

{

    int i,j,k,l,cur,qian,hou;

memset(dis,-1,sizeof(dis));

qian=hou=0;

q[qian++]=0;

dis[0]=0;

    while(qian!=hou)//判断模拟循环队列是否为空

{

cur=q[hou++];//取队首元素并出队

        if(hou>=M)hou=0;//循环队列

        for(i=hand[cur];i!=-1;i=s[i].next)//线性表中快速遍历与cur相关的点

{

k=s[i].to;//取出点

            if(s[i].val>0&&dis[k]==-1)//判断流量限制和是否已经分层

{

dis[k]=dis[cur]+1;//分层

q[qian++]=k;//入队

                if(qian>=M)qian=0;//循环队列

                if(k==1001)return
1
;//已经分层汇点

}

}

}

    return 0;//到最后都没有搜到汇点表示没有增广路了

}

int dfs(int x,int flow)

{

    int i,j,k,l,cost=0;

    if(flow<=0)return
0;

    if(x==1001)return
flow;//汇点

    for(i=hand[x];i!=-1;i=s[i].next)//遍历相关点

{

k=s[i].to;//取点

        if(s[i].val>0&&dis[k]==dis[x]+1)//判断流量限制和层次关系是否符合

{

l=dfs(k,Min(flow-cost,s[i].val));//向下搜索,流量限制取当前剩余流量和路径限制流量中的最小值

            if(l>0)//向下搜到汇点则确定这一条路径

{

cost+=l;//当前路径的最小流量加入到总流量消耗值中

s[i].val-=l;//正向减少

s[i^1].val+=l;//反正增加

                if(cost==flow)break;//当前点满流则结束

}else dis[k]=-1;//向下搜不到汇点则切断这条路,相当于深搜中vis的作用

}

}

    return cost;

}

void dinic()

{

    int i,j,k,l=0;

    while(bfs())//分层并判断原点是否与汇点相通

{

l+=dfs(0,MAX);//深搜在当前分层中找出最大流

}

    if(l>=sum)puts("Yes");//最大流可能大于预判,因为任务在最大时间点之前就全部完成了

    else puts("No");

}

int main (void)

{

    int t,cas=1,i,j,k,l,Pi,Si,Ei;

scanf("%d",&t);

    while(t--&&scanf("%d%d",&n,&m))

{

snum=sum=0;

memset(hand,-1,sizeof(hand));

        for(i=1;i<=n;i++)

{

scanf("%d%d%d",&Pi,&Si,&Ei);

setit(0,i,Pi);//我设置的是0为原点,1到n是任务,这里是连接原点跟任务

sum+=Pi;//记录总花费时间

            while(Si<=Ei)//遍历当前任务相关的所有时间点

{

setit(i,500+Si,1);//最大任务数是500,所以时间我设置是501到1000,这里是连接任务和相关时间

Si++;

}

}

        for(i=501;i<=1000;i++)

setit(i,1001,m);//我设置的汇点是1001,这里是连接所有时间点跟汇点(不管是否在任务范围,这是为了偷懒和方便)

printf("Case %d: ",cas++);

dinic();

puts("");//格式。。

}

    return 0;

}

心得:我也是醉了,开始绘图错了,到后来算法时间度我没有深入了解,以至于到了大半夜还在装13卖萌充当学霸,但是给我的收货是学算法不光是了解他的用法和熟练去写它,还需要充分了解它的部分原理,学习其中一些深层的却不起眼的东西,往往这知识点关键时候就是你制胜的关键··

时间: 2024-12-27 00:11:21

HDU--杭电--3572--Task Schedule--最大流的相关文章

HDU 3572 Task Schedule (最大流)

C - Task Schedule Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Practice HDU 3572 Description Our geometry princess XMM has stoped her study in computational geometry to concentrate on her newly opened fac

hdu 3572 Task Schedule 最大流 Dinic算法,,卡时间。。建图非常有讲究

Task Schedule Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 4617    Accepted Submission(s): 1513 Problem Description Our geometry princess XMM has stoped her study in computational geometry t

hdu 3572 Task Schedule(最大流)

hdu 3572 Task Schedule Description Our geometry princess XMM has stoped her study in computational geometry to concentrate on her newly opened factory. Her factory has introduced M new machines in order to process the coming N tasks. For the i-th tas

HDU 3572 Task Schedule(ISAP)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3572 题意:m台机器,需要做n个任务.第i个任务,你需要使用机器Pi天,且这个任务要在[Si  ,  Ei]区间内完成才有效.对于一个任务,只能由一个机器来完成,一个机器同一时间只能做一个任务.当然,一个任务可以分成几段不连续的时间来完成.问,能否做完全部任务. 题意很清晰,也就是判断是否是满流. 对于网络流问题,模板大家都有,关键在于如何建图(详见资料) 思路:今天问了龙哥,对建图有了一定的了解,

hdu 3572 Task Schedule(网络流 dinic算法)

Task Schedule Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 3412    Accepted Submission(s): 1197 Problem Description Our geometry princess XMM has stoped her study in computational geometry t

hdoj 3572 Task Schedule【最大流】

题目:hdoj 3572 Task Schedule 题意:有m台机器和n个任务,然后给出每个任务的开始时间和结束时间以及需要的天数,让你判断有没有这样条件的安排 分析:网络流题目,比较难想到的是把时间区间怎么在图里面建,其实是在这个区间的每个点都连一条边,建图方案. 超级源点s到每个任务 i 连边,容量为第 i 个任务需要的天数,然后每个任务向满足要求的日期连一条容量为1的边,即从开始到结束都连,然后所有日期到汇点连容量m的边,因为每个机器最多同时能够做m个task. 这样建图发现图中的点最多

『ACM C++』HDU杭电OJ | 1415 - Jugs (灌水定理引申)

今天总算开学了,当了班长就是麻烦,明明自己没买书却要带着一波人去领书,那能怎么办呢,只能说我善人心肠哈哈哈,不过我脑子里突然浮起一个念头,大二还要不要继续当这个班委呢,既然已经体验过就可以适当放下了吧,用心在自己的研究上.晚上级会开完也就八点多了,开始打打题,今天在HDU杭电的ACM集训题看到一个奇葩的题,前来献上. 今日推荐: <全球风暴> 一部宇宙航空和地球气候片的良心佳作,后期特效建模都是特别杠杠的大片,不会让你失望的哟,我已经三刷了哈哈哈.这部片在爱奇艺有上线,有兴趣的朋友可以看看鸭.

HDU 3572 Task Schedule(拆点+最大流dinic)

Task Schedule Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 7753    Accepted Submission(s): 2381 Problem Description Our geometry princess XMM has stoped her study in computational geometry t

hdu 3572 Task Schedule

Task Schedule Problem Description Our geometry princess XMM has stoped her study in computational geometry to concentrate on her newly opened factory. Her factory has introduced M new machines in order to process the coming N tasks. For the i-th task

【HDU】 3572 Task Schedule

Task Schedule 题目链接 Task Schedule 题目大意 总共有m个机器,n个任务,每个任务具有Si,Ei,Pi,三种属性,从Si到Ei,总共需要Pi天去完成,每个机器同一时间只能运行一个任务,任务运行时可以被中断去完成其他任务.现在问是否有一种调度方法,使这n个任务能全部完成. 题解 这一题是网络流的题目,难点在于如何建图. 因为每个任务都可以在Si到Ei内任何一个时间运行,我们想到从每个任务向这些可行的时间点建边,又因为每个任务需要运行Pi天,所以我们建立一个源点,向每个任