zoukankan      html  css  js  c++  java
  • hdu 3572(构图+最大流)

    Task Schedule

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


    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台机器,其中完成第i个任务需要p[i]天,需要在第s[i]天或者其之后开始,需要在第e[i]天或者其之前完成,任务可以随时开始或者停止,问在给定的条件下能否完成所有的任务。
    题解:构造超级源点以及超级汇点,超级源点向每个i点连一条容量为p[i]的边,每一个i点向其起始天和完成天区间内的每一天连一条容量为1的边,然后所有的天都向所有的机器连一条容量为1的边,最后所有的机器向汇点连一条无穷大的边,做一次最大流,如果max_flow == sum(p[i]),则证明能够完成所有的任务,别把下标弄混了。。弄错了一个下标,WA了两次。
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include <algorithm>
    #include <math.h>
    #include <queue>
    using namespace std;
    const int N = 10000;
    const int INF = 999999999;
    struct Edge{
        int v,w,next;
    }edge[N*N];
    int head[N];
    int p[N],s[N],e[N];
    int level[N];
    int tot,n,m;
    void init()
    {
        memset(head,-1,sizeof(head));
        tot=0;
    }
    void addEdge(int u,int v,int w,int &k)
    {
        edge[k].v = v,edge[k].w=w,edge[k].next=head[u],head[u]=k++;
        edge[k].v = u,edge[k].w=0,edge[k].next=head[v],head[v]=k++;
    }
    int BFS(int src,int des)
    {
        queue<int>q;
        memset(level,0,sizeof(level));
        level[src]=1;
        q.push(src);
        while(!q.empty())
        {
            int u = q.front();
            q.pop();
            if(u==des) return 1;
            for(int k = head[u]; k!=-1; k=edge[k].next)
            {
                int v = edge[k].v;
                int w = edge[k].w;
                if(level[v]==0&&w!=0)
                {
                    level[v]=level[u]+1;
                    q.push(v);
                }
            }
        }
        return -1;
    }
    int dfs(int u,int des,int increaseRoad){
        if(u==des||increaseRoad==0) return increaseRoad;
        int ret=0;
        for(int k=head[u];k!=-1;k=edge[k].next){
            int v = edge[k].v,w=edge[k].w;
            if(level[v]==level[u]+1&&w!=0){
                int MIN = min(increaseRoad-ret,w);
                w = dfs(v,des,MIN);
                if(w > 0)
                {
                    edge[k].w -=w;
                    edge[k^1].w+=w;
                    ret+=w;
                    if(ret==increaseRoad) return ret;
                }
                else level[v] = -1;
                if(increaseRoad==0) break;
            }
        }
        if(ret==0) level[u]=-1;
        return ret;
    }
    int Dinic(int src,int des)
    {
        int ans = 0;
        while(BFS(src,des)!=-1) ans+=dfs(src,des,INF);
        return ans;
    }
    int main()
    {
        int tcase;
        scanf("%d",&tcase);
        int t = 1;
        while(tcase--){
            init();
            scanf("%d%d",&n,&m);
            int MIN = INF,MAX = -1,sum = 0;
            for(int i=1;i<=n;i++){
                scanf("%d%d%d",&p[i],&s[i],&e[i]);
                MIN = min(s[i],MIN);
                MAX = max(e[i],MAX);
                sum+=p[i];
            }
            int start = 0,ed = n+(MAX-MIN+1)+m+1;
            for(int i=1;i<=n;i++){
                addEdge(start,i,p[i],tot);
            }
            for(int i=1;i<=n;i++){
                for(int j=s[i]+n;j<=e[i]+n;j++){
                    addEdge(i,j,1,tot);
                }
            }
            for(int i=MIN+n;i<=MAX+n;i++){
                for(int j=n+MAX-MIN+1+1;j<ed;j++){
                    addEdge(i,j,1,tot);
                }
            }
            for(int i=n+MAX-MIN+1+1;i<ed;i++){
                addEdge(i,ed,INF,tot);
            }
            int max_flow = Dinic(start,ed);
            printf("Case %d: ",t++);
            if(max_flow==sum){
                printf("Yes
    ");
            }else{
                printf("No
    ");
            }
            printf("
    ");
        }
        return 0;
    }
  • 相关阅读:
    结对编程:黄金点小游戏
    在win7环境下如何安装Microsoft Visual Studio
    软件工程第一次作业
    Android关于保存数据(Saving data)
    Android bitmap和canvas小记(转)
    java/android开发中删除文件
    博客园的第一篇
    安卓初学者必看实例,(计算圆面积)
    安卓初学者必看实例,(文件管理器简单实现)
    安卓初学者必看实例,(访问sqlite)
  • 原文地址:https://www.cnblogs.com/liyinggang/p/5720303.html
Copyright © 2011-2022 走看看