zoukankan      html  css  js  c++  java
  • HDU3572_Task Schedule(网络流最大流)

    解题报告

    题意:

    工厂有m台机器,须要做n个任务。对于一个任务i。你须要花费一个机器Pi天,并且,開始做这个任务的时间要>=Si,完毕这个任务的时间<=Ei。

    对于一个任务,仅仅能由一个机器来完毕。一个机器同一时间仅仅能做一个任务。

    可是,一个任务能够分成几段不连续的时间来完毕。问,是否能做完所有任务。

    思路:

    网络流在于建模,这题建模方式是:

    把每一天和每一个任务看做点。由源点到每一任务。建容量为pi的边(表示任务须要多少天完毕)。

    每一个任务每一天,若是能够在这天做任务,建一条容量为1的边。最后。把每天到汇点再建一条边容量m(表示每台机器最多工作m个任务)。

    #include <map>
    #include <queue>
    #include <vector>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #define inf 99999999
    using namespace std;
    int n,m,l[2010],head[2010],cnt,M;
    struct node
    {
        int v,w,next;
    } edge[555000];
    void add(int u,int v,int w)
    {
        edge[M].v=v;
        edge[M].w=w;
        edge[M].next=head[u];
        head[u]=M++;
    
        edge[M].v=u;
        edge[M].w=0;
        edge[M].next=head[v];
        head[v]=M++;
    }
    int bfs()
    {
        memset(l,-1,sizeof(l));
        l[0]=0;
        int i,u,v;
        queue<int >Q;
        Q.push(0);
        while(!Q.empty())
        {
            u=Q.front();
            Q.pop();
            for(i=head[u]; i!=-1; i=edge[i].next)
            {
                v=edge[i].v;
                if(l[v]==-1&&edge[i].w>0)
                {
                    l[v]=l[u]+1;
                    Q.push(v);
                }
            }
        }
        if(l[cnt]>0)return 1;
        return 0;
    }
    int dfs(int u,int f)
    {
        int a,i;
        if(u==cnt)return f;
        for(i=head[u]; i!=-1; i=edge[i].next)
        {
            int v=edge[i].v;
            if(l[v]==l[u]+1&&edge[i].w>0&&(a=dfs(v,min(f,edge[i].w))))
            {
                edge[i].w-=a;
                edge[i^1].w+=a;
                return a;
            }
        }
        l[u]=-1;//没加优化会T
        return 0;
    }
    int main()
    {
        int t,i,j,s,p,e,k=1;
        scanf("%d",&t);
        while(t--)
        {
            M=0;
            memset(head,-1,sizeof(head));
            scanf("%d%d",&n,&m);
            int sum=0,maxx=0;
            for(i=1; i<=n; i++)
            {
                scanf("%d%d%d",&p,&s,&e);
                add(0,i,p);
                sum+=p;
                if(maxx<e)
                    maxx=e;
                for(j=s; j<=e; j++)
                    add(i,j+n,1);
            }
            cnt=n+maxx+1;
            for(i=1; i<=maxx; i++)
            {
                add(n+i,cnt,m);
            }
            int ans=0,a;
            while(bfs())
                while(a=dfs(0,inf))
                    ans+=a;
            printf("Case %d: ",k++);
            if(ans==sum)
                printf("Yes
    ");
            else printf("No
    ");
            printf("
    ");
        }
        return 0;
    }
    

    Task Schedule

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


    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
     

    Author
    allenlowesy
     

    Source
     


  • 相关阅读:
    P2802 【回家】
    P1706 【全排列问题】
    P1936 【水晶灯火灵】
    P1319 【压缩技术】
    P2670 【扫雷游戏】
    P1097 【统计数字】
    P1820 【寻找AP数】
    P1020 【导弹拦截】
    链表反转
    队列:队列在有限线程池中的应用
  • 原文地址:https://www.cnblogs.com/yxwkf/p/5155615.html
Copyright © 2011-2022 走看看