hdu 3572 仪器与任务 最大流 好题 体会建图思想

Task Schedule

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 6802    Accepted Submission(s): 2124

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

题意:给N个任务,M台机器。每个任务有最早才能开始做的时间S,deadline E,和持续工作的时间P。每个任务可以分段进行,但是在同一时刻,一台机器最多只能执行一个任务. 问存不存在可行的工作时间。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <queue>
#include <map>
#include <algorithm>
#include <set>
using namespace std;
#define MM(a,b) memset(a,b,sizeof(a))
typedef long long ll;
typedef unsigned long long ULL;
const int mod = 1000000007;
const double eps = 1e-10;
const int inf = 0x3f3f3f3f;
const int big=50000;
int max(int a,int b) {return a>b?a:b;};
int min(int a,int b) {return a<b?a:b;};
struct edge{
   int to,cap,rev;
};

vector<edge> G[1010];
map<string,int> mp;
int n,m,k,daymax,level[1010],iter[1010];
int p[1010],s[1010],e[1010],sum;

void add_edge(int u,int v,int cap)
{
    G[u].push_back(edge{v,cap,G[v].size()});
    G[v].push_back(edge{u,0,G[u].size()-1});
}

void bfs(int s)
{
    queue<int> q;
    q.push(s);
    level[s]=1;
    while(q.size())
    {
        int now=q.front();q.pop();
        for(int i=0;i<G[now].size();i++)
        if(G[now][i].cap>0)
        {
            edge e=G[now][i];
            if(level[e.to]<0)
              {
                  level[e.to]=level[now]+1;
                  q.push(e.to);
              }
        }
    }
}
int dfs(int s,int t,int minn)
{
    if(s==t)
        return minn;
    for(int &i=iter[s];i<G[s].size();i++)
    {
        edge &e=G[s][i];
        if(level[e.to]>level[s]&&e.cap>0)
        {
            int k=dfs(e.to,t,min(minn,e.cap));
            if(k>0)
             {
                 e.cap-=k;
                 G[e.to][e.rev].cap+=k;
                 return k;
             }
        }
    }
    return 0;
}

int max_flow(int s,int t)
{
    int ans=0,temp;
    for(;;)
    {
        memset(level,-1,sizeof(level));
        bfs(s);
        if(level[t]<0)
            return ans;
        memset(iter,0,sizeof(iter));
        while((temp=dfs(s,t,inf))>0)
            ans+=temp;
    }
    return ans;
}

void build()
{
    for(int i=0;i<=n+daymax+1;i++) G[i].clear();

    for(int i=1;i<=n;i++)
       add_edge(0,i,p[i]);

    for(int i=n+1;i<=n+daymax;i++)
       add_edge(i,n+daymax+1,m);

    for(int i=1;i<=n;i++)
        for(int j=1;j<=daymax;j++)
        if(j>=s[i]&&j<=e[i])
            add_edge(i,j+n,1);
}

int main()
{
    int cas,kk=0;
    scanf("%d",&cas);
    while(cas--)
    {
        daymax=0;sum=0;
        scanf("%d %d",&n,&m);
        for(int i=1;i<=n;i++)
                {
                    scanf("%d %d %d",&p[i],&s[i],&e[i]);
                    if(e[i]>daymax) daymax=e[i];
                    sum+=p[i];
                }

        build();
        printf("Case %d: ",++kk);
        if(max_flow(0,n+daymax+1)==sum)
           printf("Yes\n");//刚开始输出YES,wa了好久,剁手了,以后输出格式都直接粘贴!
        else printf("No\n");
        printf("\n");
    }
    return 0;
}

  体会建图思想,刚开始我想的是建立一个天数与机器的二元组,然后向汇点连接一条容量为1的边,但是算下来就是会超时了,,因为点太多了,,,其实只要将天数向汇点连接容量为仪器数量的边就好了,这样就控制了仪器的使用数量,然后就是任务向仪器连边,跑跑最大流就可以了

时间: 2024-11-03 03:27:09

hdu 3572 仪器与任务 最大流 好题 体会建图思想的相关文章

hdu 3549 Flow Problem(最大流模板题)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3549 Problem Description Network flow is a well-known difficult problem for ACMers. Given a graph, your task is to find out the maximum flow for the weighted directed graph. Input The first line of input

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【 最大流 】

求出最大流,再判断是否满流 先不理解为什么要这样建图 后来看了这一篇题解 http://blog.csdn.net/u012350533/article/details/12361003 把0看做源点st 把每一个任务看做一个点 st到每个任务连边,容量为p,表示任务完成需要的天数 每个任务到每个任务的开始至结束时间连边,容量为1,表示这个任务可以在这些天完成 每一天向汇点ed连边,容量为m,表示一天最多运行m个任务 然后判断最大流是否等于执行完所有任务所需要的时间 1 #include<cst

[ACM] hdu 3549 Flow Problem (最大流模板题)

Flow Problem Problem Description Network flow is a well-known difficult problem for ACMers. Given a graph, your task is to find out the maximum flow for the weighted directed graph. Input The first line of input contains an integer T, denoting the nu

HDU3572Task Schedule(最大流 ISAP比较快)建图方法不错

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

HDU3338Kakuro Extension(最大流,ISAP)建图是关键

Kakuro Extension Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1144    Accepted Submission(s): 404 Special Judge Problem Description If you solved problem like this, forget it.Because you nee

BZOJ 3218 A+B Problem(最大流 + 主席树优化建图)

题目:A+B Problem 感谢 Nietzsche 在省选紧迫之际花 39' 给我讲这道题. 这题我并没有想出来,感觉又浪费一道好题了. 需要用最小割,建模方式如下(假设若 2 取黑色,1 取白色会使 2 为奇怪方格): 跑一边最大流,求出最小割,用所有的 W + 所有的 B - 最小割,就是答案. 不过,对于每一个结点 2,在寻找像 1 这样(li <= aj <= ri)的结点时,总不能一个一个枚举吧? O(n2) T 飞. 所以,需要用主席树优化一下.线段树优化建图笔记. 代码未完待

HDU 3572 Task Schedule(最大流判断满流)

https://vjudge.net/problem/HDU-3572 题意: 有N个作业和M台机器,每个作业都有一个持续时间P,工作的日期为S~E.作业可以断断续续的在不同机器上做,每台机器每次只可以处理一个作业.判断是否可以在作业的工作日期内完成所有作业. 思路: 建立源点0和汇点t,因为天数最多为500,所有我们将日期的编号定为1~500,作业的编号为500+i. 对于每个作业,与源点0相连,容量为P,意味着它必须走完这P容量才能完成这作业.与S~E相连,容量为1.日期与汇点相连,容量为m

HDU - 3572 Task Schedule (最大流)

题目大意:有N个任务,M台机器. 每个任务有相应的起始时间,截至时间和完成时间 每台机器一小时可以做1个单位的工作量,每个任务的完成可以不连续,但每次只能由一台机器完成 问能否完成所有任务 解题思路:因为只有500分钟,所以可以将每分钟都设成1条边,连向超级汇点,容量为M 每个任务连接向超级源点,容量为完成时间 接着将任务连接像时间(分钟),连接的条件为,该时间在起始时间和截止时间这个区间之内 这样图就构成了 #include <cstdio> #include <cstring>