hdoj 3572 Task Schedule【最大流】

题目:hdoj 3572 Task Schedule

题意:有m台机器和n个任务,然后给出每个任务的开始时间和结束时间以及需要的天数,让你判断有没有这样条件的安排

分析:网络流题目,比较难想到的是把时间区间怎么在图里面建,其实是在这个区间的每个点都连一条边,建图方案。

超级源点s到每个任务 i 连边,容量为第 i 个任务需要的天数,然后每个任务向满足要求的日期连一条容量为1的边,即从开始到结束都连,然后所有日期到汇点连容量m的边,因为每个机器最多同时能够做m个task。

这样建图发现图中的点最多1000个,边非常多,显然是一个稠密图,那么EK算法的复杂度显然不满足,我选择用dinci。

dinci有三个优化,这里一个不能少,否则都会超时。都是深搜里面的技巧,一定注意。

AC代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
#define Del(a,b) memset(a,b,sizeof(a))
const int N = 1020;
const int inf = 0x3f3f3f3f;
int n,m;
struct Node
{
    int from,to,cap,flow;
};
vector<int> v[N];
vector<Node> e;
int vis[N];  //构建层次图
int cur[N];
void add_Node(int from,int to,int cap)
{
    e.push_back((Node){from,to,cap,0});
    e.push_back((Node){to,from,0,0});
    int tmp=e.size();
    v[from].push_back(tmp-2);
    v[to].push_back(tmp-1);
}
bool bfs(int s,int t)
{
    Del(vis,-1);
    queue<int> q;
    q.push(s);
    vis[s] = 0;
    while(!q.empty())
    {
        int x=q.front();
        q.pop();
        for(int i=0;i<v[x].size();i++)
        {
            Node tmp = e[v[x][i]];
            if(vis[tmp.to]<0 && tmp.cap>tmp.flow)  //第二个条件保证
            {
                vis[tmp.to]=vis[x]+1;
                q.push(tmp.to);
            }
        }
    }
    if(vis[t]>0)
        return true;
    return false;
}
int dfs(int o,int f,int t)
{
    if(o==t || f==0)  //优化
        return f;
    int a = 0,ans=0;
    for(int &i=cur[o];i<v[o].size();i++) //注意前面 ’&‘,很重要的优化
    {
        Node &tmp = e[v[o][i]];
        if(vis[tmp.to]==(vis[o]+1) && (a = dfs(tmp.to,min(f,tmp.cap-tmp.flow),t))>0)
        {
            tmp.flow+=a;
            e[v[o][i]^1].flow-=a; //存图方式
            ans+=a;
            f-=a;
            if(f==0)  //注意优化
                break;
        }
    }
    return ans;  //优化
}

int dinci(int s,int t)
{
    int ans=0;
    while(bfs(s,t))
    {
        Del(cur,0);
        int tm=dfs(s,inf,t);
        ans+=tm;
    }
    return ans;
}
int main()
{
    //freopen("Input.txt","r",stdin);
    int T;
    scanf("%d",&T);
    for(int cas=1;cas<=T;cas++)
    {
        scanf("%d%d",&n,&m);
        int s=0,ma=0,count=0;
        for(int i=1;i<=n;i++)
        {
            int day,st,en;
            scanf("%d%d%d",&day,&st,&en);
            count+=day;
            add_Node(s,i,day);
            for(int j=st;j<=en;j++)
                add_Node(i,n+j,1);
            ma=max(ma,en);
        }
        int t=n+ma+1;
        for(int i=1;i<=ma;i++)
        {
            add_Node(n+i,t,m);
        }
        int ans=dinci(s,t);
        if(ans==count)
            printf("Case %d: Yes\n",cas);
        else
            printf("Case %d: No\n",cas);
        printf("\n");
        for(int i=0;i<=t;i++)
            v[i].clear();
        e.clear();
    }
    return 0;
}
时间: 2024-12-26 22:03:19

hdoj 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 4907 Task schedule 【预处理】

题意:中文题,你懂得... 思路:建两个数组,一个标记,一个放答案(就是最快能处理的任务点), 在输入数据的时候标记改位置已经有任务了,并且找出来一个最大的数max.然后从max+1,出发从大到小,依次用temp定义没有任务的序号,如果是没有被标记那么就将该处的答案定义为temp. 题目链接 点击打开链接 代码: #include<stdio.h> #include<string.h> #define MAXN 200005 int vis[MAXN], ans[MAXN]; in

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天,所以我们建立一个源点,向每个任