HDU3572构造图的模型

Posted df-yimeng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU3572构造图的模型相关的知识,希望对你有一定的参考价值。

第一次面对建模的图,也映照了我以前想的算法不是重点,问题的转化才是重点

Description:

  N个任务,M台机器,对于每一个任务有p,s,e表示该任务要做p个时长,要从[s,……)开始,从(……e]结束,问你这些任务最后能完成吗Yes || No

Solution:

  做的是最大流专辑,知道是最大流的题目,但是就是不知道怎么转化为最大流的问题。。。

  Yes or No的关键就是最大流能否等于任务总时长,面对这个题,对于每一个任务 i ,从源点到i添加一条边,边的权值(容量)是对应任务的p,如果yes是不是从s流出的量 fmax == sum(p),假设这些流量流到了任务,那么任务如何处理呢,就是看看时间段如何分配,因为可以任意时间段开始,暂停直到结束所以每个任务与它对应的每一个时间段都要添加一个1(容量),不管这个任务咋分配,只要能分配给它的p就行了,那分配好时间段了呢,是不是还有一个条件也就是机器数目,同一个时间最多m个机器工作,所以每一个时间段,都要向汇点T,传入一个m的容量,表示的意义也很明显啦,最后求出最大流就好了!真舒服,第一次懂一类题的感觉应该都是这样的吧略略略

 要注意一下,最多有多少边哈·

#include <iostream>
#include <cstdio>
#include <string.h>
#include <queue>
#include <cmath>
#include <algorithm>

#define inf (1 << 28)
using namespace std;
typedef long long ll;
const int maxn = 5000;
const int maxm = 251000+7;
int n,m;
int S,T;
struct node{
    int pre;
    int to,cost;
}e[maxm<<1];
int id[maxn],cnt;
int flor[maxn];

int cur[maxn];//DFS的优化遍历

void add(int from,int to,int cost)
{
    e[cnt].to = to;
    e[cnt].cost = cost;
    e[cnt].pre = id[from];
    id[from] = cnt++;
    swap(from,to);
    e[cnt].to = to;
    e[cnt].cost = 0;
    e[cnt].pre = id[from];
    id[from] = cnt++;
}

int bfs(int s,int t)
{
    memset(flor,0,sizeof(flor));
    queue < int > q;
        while(q.size())q.pop();
    flor[s] = 1;
    q.push(s);

    while(q.size())
    {
        int now = q.front();
        q.pop();
        for(int i = id[now];~i;i=e[i].pre)
        {
            int to = e[i].to;
            int cost = e[i].cost;
            if(flor[to] == 0 && cost > 0)
            {
                flor[to] = flor[now] + 1;
                q.push(to);
                if(to == t)return 1;
            }
        }
    }
    return 0;
}
int dfs(int s,int t,int value)
{
    //ret表示目前流到s的最大流量,用来计算回溯的时候是否还有可行流
    int ret = value;
    if(s == t || value == 0)return value;

    int a;

    for(int &i = cur[s];~i;i = e[i].pre)
    {
        int to = e[i].to;
        int cost = e[i].cost;
        if(flor[to] == flor[s] + 1 && (a = dfs(to,t,min(ret,cost))))
        {
            e[i].cost -= a;
            e[i^1].cost += a;
            ret -= a;
            if(ret == 0)break;
        }
    }
    //s点后面没有可行的流了
    if(ret == value) flor[s] = 0;
    return value - ret;
}
int dinic(int s,int t)
{
    ll ret = 0;
    while(bfs(s,t))
    {
        memcpy(cur,id,sizeof(id));
        ret += dfs(s,t,inf);
    }
    return ret;
}
void init()
{
    memset(id,-1,sizeof(id));
    cnt = 0;
}
int main()
{
    int t;
    scanf("%d",&t);
    int cas = 0;
    while(t--)
    {
        scanf("%d%d",&n,&m);
        init();
        int p,s,e;
        int tl = -1,tr = -1;
        S = 0;
        int sump = 0;
        for(int i = 1;i <= n;++i)
        {
            scanf("%d%d%d",&p,&s,&e);
            sump += p;
            add(S,i,p);
            if(tl == -1)tl = s;
            if(tr == -1)tr = e;
            tl = min(tl,s);
            tr = max(tr,e);

            for(int j = s;j <= e;++j)
            {
                add(i,n+j,1);
            }
        }
        T = n + tr + 1;
        for(int i = tl;i <= tr;++i)
        {
            add(n + i,T,m);
        }
        ll ret = dinic(S,T);
        printf("Case %d: %s

",++cas,ret == sump ? "Yes" : "No");
    }
    return 0;
}

 

以上是关于HDU3572构造图的模型的主要内容,如果未能解决你的问题,请参考以下文章

HDU-3572-Task Schedule

hdu3572 最大流

HDU 3572 最大流

hdu 3572 Task Schedule

hdu 3572 Task Schedule (Dinic模板)

HDU3572 Task Schedule 最大流