HDU 3572 Task Schedule

  这种题一开始完全想不出模型,题目做多了之后就有感觉了。

  对于这道题,求一次最大流,判断是否满流就可以了。

  建图:添加超级源点和汇点,对于每个任务,从源点向其连一条边,权值为Pi,因为要保证每个任务做够Pi天,然后把时限区间 si ~ ei 拆成一天一天的,那么该任务对应到一天连权值为1的边,最后,对于某一天,因为有m台机器可以同时工作,那么这一天向汇点连一条边,权值为m,求最大流。

/* HDU 3549 Flow Problem */
#include <vector>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <deque>
#include <stack>
#include <algorithm>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <queue>
using namespace std;
#define pii         pair<int,int>
#define clr(a)      memset((a),0,sizeof (a))
#define rep(i,a,b)  for(int i=(a);i<=(int)(b);i++)
#define per(i,a,b)  for(int i=(a);i>=(int)(b);i--)
#define inf         1e9
#define eps         1e-6
#define MAXN        1005
#define MAXM        1000005
#define MODN        1000000007
#define debug       puts("reach here")
#define MP          make_pair
#define PB          push_back
#define RI(x)       scanf("%d",&x)
#define RII(x,y)    scanf("%d%d",&x,&y)
#define RIII(x,y,z) scanf("%d%d%d",&x,&y,&z)
typedef long long LL;

struct Edge
{
    int v, w, next;
}E[MAXM];   
int head[MAXN], NE; 

int n, m;
int gap[MAXN],dis[MAXN],pre[MAXN],cur[MAXN];

void add_edge (int u, int v, int w)
{
    E[NE].v = v;   
    E[NE].w = w;
    E[NE].next = head[u];
    head[u] = NE++;
    
    E[NE].v = u;
    E[NE].w = 0;
    E[NE].next = head[v];
    head[v] = NE++;
}

inline void checkmin(int &a,int b)  {if(a == -1 || a > b)a = b;}

int sap(int s,int t)
{
    memset(dis,0,sizeof dis);
    memset(gap,0,sizeof gap);
    for(int i=0;i<n;++i) cur[i]=head[i];
    int u=pre[s]=s,maxflow=0,aug=-1;
    gap[0]=n;
    while(dis[s]<n)
    {
loop:for(int &i=cur[u];i!=-1;i=E[i].next)
        {
            int v=E[i].v;
            if(E[i].w && dis[u]==dis[v]+1)
            {
                checkmin(aug,E[i].w);
                pre[v]=u;
                u=v;
                if(v==t)
                {
                    maxflow+=aug;
                    for(u=pre[u];v!=s;v=u,u=pre[u])
                    {
                        E[cur[u]].w-=aug;
                        E[cur[u]^1].w+=aug;
                    }
                    aug=-1;
                }
                goto loop;
            }
        }
        int mindis=n;
        for(int i=head[u];i!=-1;i=E[i].next)
        {
            int v=E[i].v;
            if(E[i].w && mindis>dis[v])
            {
                cur[u]=i;
                mindis=dis[v];
            }
        }
        if((--gap[dis[u]])==0) break;
        gap[dis[u]=mindis+1]++;
        u=pre[u];
    }
    return maxflow;
}

void init()
{
    NE = 0;
    memset(head, -1, sizeof head);
}

int main()
{
    int p, s, e;
    int t, sum;
    int cas = 1;
    scanf("%d", &t);
    while(t--)
    {
        scanf("%d%d", &n, &m);
        init();
        sum = 0;
        int l = inf, r = -1;
        rep(i,1,n)
        {
            RIII(p, s, e);
            add_edge(0,i,p);
            sum += p;
            l = min(l, s);
            r = max(r, e);
            rep(j,s+n,e+n)
                add_edge(i, j, 1);
        }
        
        int des = 1 + r + n;
        rep(i,1,r)
            add_edge(i+n,des,m);
        n = des + 1;
        int ans = sap(0, des);
        printf("Case %d: %s\n\n", cas++, ans == sum ? "Yes" : "No");
    }
    return 0;
}
View Code

相关文章:

  • 2021-08-05
  • 2022-12-23
  • 2022-01-01
  • 2021-09-17
  • 2021-12-23
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-12-23
  • 2021-09-09
相关资源
相似解决方案