zoukankan      html  css  js  c++  java
  • 【最大流】【HDU3572】Task Schedule

    题意:

    有N个事件,M台机器。事件有开始时间,持续时间,要在结束时间之前完成,问是否能完成所有事件?


    非自己思考出来的

    建图:把每个任务和每一天都看做一个点,添加源点和汇点。源点与每个任务之间连一条边,容量为完成该任务所需处理次数。若第i个任务可以在Si至Ei天处理,则由该任务向这些天分别连一条边,容量为1,表示此任务每天只能被处理一次。最后,从每一天连一条到汇点的边,容量为机器数M,表示每天可以处理M个任务。若求出的最大流等于所有任务需要处理的次数之和,说明能完成任务;否则,不能完成任务。


    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <cstring>
    #include <ctime>
    #include <algorithm>
    #include <iostream>
    #include <sstream>
    #include <string>
    #define oo 0x13131313
    using namespace std;
    int N,M;
    using namespace std;
    const int MAXN=5000+5;
    const int MAXM=300000+5;
    const int INF=0x3f3f3f3f;
    const int TT=500+500+2;
    const int S=0;
    struct Edge
    {
        int to,next,cap,flow;
        void get(int a,int b,int c,int d)
        {
            to=a;next=b;cap=c;flow=d;
        }
    }edge[MAXM];
    int tol;
    int head[MAXN];
    int gap[MAXN],dep[MAXN],pre[MAXN],cur[MAXN];
    void init()
    {
        tol=0;
        memset(head,-1,sizeof(head));
    }
    //单向图三个参数,无向图四个参数
    void addedge(int u,int v,int w,int rw=0)
    {
        edge[tol].get(v,head[u],w,0);head[u]=tol++;
        edge[tol].get(u,head[v],rw,0);head[v]=tol++;
    }
    int sap(int start,int end,int N)
    {
        memset(gap,0,sizeof(gap));
        memset(dep,0,sizeof(dep));
        memcpy(cur,head,sizeof(head));
        int u=start;
        pre[u]=-1;
        gap[0]=N;
        int ans=0;
        while(dep[start]<N)
        {
            if(u==end)
            {
                int Min=INF;
                for(int i=pre[u];i!=-1;i=pre[edge[i^1].to])
                    if(Min>edge[i].cap-edge[i].flow)
                       Min=edge[i].cap-edge[i].flow;
                for(int i=pre[u];i!=-1;i=pre[edge[i^1].to])
                {
                    edge[i].flow+=Min;
                    edge[i^1].flow-=Min;
                }
                u = start;
                ans+=Min;
                continue;
            }
            bool flag=false;
            int v;
            for(int i=cur[u];i !=-1;i=edge[i].next)
            {
                v=edge[i].to;
                if(edge[i].cap-edge[i].flow&&dep[v]+1==dep[u])
                {
                    flag=true;
                    cur[u]=pre[v]=i;
                    break;
                }
            }
            if(flag)
            {
                u=v;
                continue;
            }
            int Min=N;
            for(int i=head[u];i!=-1;i=edge[i].next)
                if(edge[i].cap-edge[i].flow&&dep[edge[i].to]<Min)
            {
                Min=dep[edge[i].to];
                cur[u]=i;
            }
            gap[dep[u]]--;
            if(!gap[dep[u]]) return ans;
            dep[u]=Min+1;
            gap[dep[u]]++;
            if(u!=start) u=edge[pre[u]^1].to;
        }
        return ans;
    }
    void File()
    {
        freopen("a.in","r",stdin);
        freopen("a.out","w",stdout);
    }
    int sum;
    void input()
    {
        sum=0;
        int p,s,e;
        cin>>N>>M;
        for(int i=1;i<=N;i++)
        {
            scanf("%d%d%d",&p,&s,&e);
            sum+=p;
            addedge(S,i,p);     //源点到任务连一条流量为p的边
            for(int j=s;j<=e;j++)
            {
                addedge(i,N+j,1);   //任务到s-e间连一条流量为1的边
            }
        }
        for(int i=1;i<=500;i++)
        {
            addedge(N+i,TT,M);         //时间到汇点连一条流量为M的边,表示一天最多处理的事情
        }
    }
    int main()
    {
      //  File();
    	int T;
    	cin>>T;
    	int CASE=0;
    	while(T--)
        {
            printf("Case %d: ",++CASE);
            init();
            input();
            if(sum==sap(S,TT,1003))
                cout<<"Yes"<<endl;
            else cout<<"No"<<endl;
            cout<<endl;
        }
    }
    


  • 相关阅读:
    操作MS SQL Server 存储过程的类(外加ASP.NET MessageBox类)
    利用DataGrid的超级联接传值
    操作数据库系统信息
    鼠标指向表格中的一行时,该行背景色改变;点击行时,突出显示标记颜色
    asp.net下的UBB代码[C#]
    java 为什么要序列化
    oracle调用java方法的例子(下面所有代码都是在sql/plus
    oracle存储过程
    一个Java程序员应该掌握的10项技能
    七款天气预报代码
  • 原文地址:https://www.cnblogs.com/zy691357966/p/5480357.html
Copyright © 2011-2022 走看看