hdu3572Task Schedule 最大流

//n个任务,m台机器

//每个任务都有开始工作的时间,结束的时间和需要一台机器工作的天数

//每个任务的工作可以断开,只需要在规定的时间内用机器工作规定天数

//在同一天,一个任务只能被一台机器工作

//问能否安排时间使得所有的任务都能在规定时间内完成

//对任务和其工作的时间建立权值为1的边

//在建立一个超级源点和一个超级汇点

//从源点向任务引入权值为该任务需要工作的天数,从每一天向汇点建立权值为m的边

//这样从源点到汇点的最大流如果大于所有的任务的需要工作的天数之和,所有任务就能在规定时间完成

dinic算法:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
using namespace std ;
const int maxn = 10010 ;
const int inf = 0x7fffffff ;
int st = 0 ;int en = 1001 ;
int dis[maxn];
struct Edge
{
    int v ;int next;
    int w ;
}edge[maxn*maxn] ;
int head[maxn] , nedge ;

void addedge(int u , int v , int w)
{
    edge[nedge].v = v ;
    edge[nedge].w = w ;
    edge[nedge].next = head[u] ;
    head[u] = nedge++ ;
    edge[nedge].v = u ;
    edge[nedge].w = 0 ;
    edge[nedge].next = head[v] ;
    head[v] = nedge++ ;
}
bool bfs()
{
    queue<int> que ;
    memset(dis , -1 ,sizeof(dis)) ;
    dis[st] = 0 ;
    que.push(st) ;
    while(que.size())
    {
        int u = que.front() ;
        que.pop() ;
        for(int i = head[u]; i != -1 ; i = edge[i].next)
        {
            int v = edge[i].v ;
            if(edge[i].w > 0 && dis[v] < 0)
            {
                dis[v] = dis[u] + 1 ;
                que.push(v) ;
            }
        }
    }
    if(dis[en] > 0)
    return true ;
    return false ;
}
int dfs(int x,int mx)
{
    if(x==en)
    return mx;
    int i;
    int ans=0;
    int a;
    for(i=head[x];i!=-1;i=edge[i].next)
    {
        int v=edge[i].v;
        if(dis[v]==dis[x]+1&&edge[i].w>0&&(a=dfs(v,min(mx,edge[i].w))))
        {
            edge[i].w -= a;
            edge[i^1].w += a;
            ans += a;
            mx -= a;
            if(!mx)
            break;
        }
    }
    if(!ans)
    dis[x] = -1; //dinic算法的主要优化
    return ans;
}

int main()
{
    //freopen("in.txt" , "r" ,stdin) ;
    int t  ; int cas = 0 ;
    int n , m ;
    scanf("%d" , &t) ;
    while(t--)
    {
        scanf("%d%d" , &n , &m) ;
        int sum = 0 ;
        memset(head ,-1 , sizeof(head)) ;
        nedge = 0 ;
        int ma = 0 ;int mi = inf ;
        for(int i = 1;i <= n;i++)
        {
            int si , ei , pi ;
            scanf("%d%d%d" ,&pi , &si , &ei) ;
            addedge(st , i , pi) ;
            sum += pi ;
            for(int j = si;j <= ei ;j++)
            addedge(i , j + 500, 1) ;
        }
        for(int j = 501 ;j <= 1000;j++)
        addedge(j , en , m) ;
        int res ;int ans = 0 ;
        while(bfs())
          while(res = dfs(st , inf))
            ans += res ;
        printf("Case %d: ",++cas) ;
        if(ans >= sum)
        puts("Yes") ;
        else puts("No");
        puts("") ;
    }
    return  0 ;
}

isap算法:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
using namespace std ;
const int maxn = 10010 ;
const int inf = 0x7fffffff ;
int st = 0 ;int en = 1001 ;    int n , m ;
int dis[maxn];int gap[maxn] ,cur[maxn],pre[maxn] ;
struct Edge
{
    int v ;int next;
    int w ;
}edge[maxn*maxn] ;
int head[maxn] , nedge ;
void addedge(int u , int v , int w)
{
    edge[nedge].v = v ;
    edge[nedge].w = w ;
    edge[nedge].next = head[u] ;
    head[u] = nedge++ ;
    edge[nedge].v = u ;
    edge[nedge].w = 0 ;
    edge[nedge].next = head[v] ;
    head[v] = nedge++ ;
}
void bfs()
{
    memset(dis, -1 , sizeof(dis)) ;
    memset(gap , 0 , sizeof(gap)) ;
    queue<int> que ;
    dis[en] = 0 ; gap[0]++ ;
    que.push(en) ;
    while(que.size())
    {
        int u = que.front() ;que.pop() ;
        for(int i = head[u] ; i != -1 ;i =  edge[i].next)
        {
            int v = edge[i].v ;
            if(dis[v] < 0 && edge[i^1].w > 0)
            {
                dis[v] = dis[u] + 1 ;
                gap[dis[v]]++ ;
                que.push(v) ;
            }
        }
    }
}
int isap()
{
    bfs() ;
    memset(pre , -1 , sizeof(pre)) ;
    memcpy(cur , head, sizeof(head)) ;
    int u = pre[st] = st ;
    gap[0] = n ;
    int  maxflow =0 ;
    int aug = inf ;bool flag  ;
    while(dis[st] < n)
    {
        flag = false ;
        for(int i = cur[u] ;i != -1 ;i = edge[i].next)
        {
            int v = edge[i].v ;
            if(dis[u] == dis[v] + 1 && edge[i].w > 0)
            {
                flag = true ;
                cur[u] = i ;
                pre[v] = u ; u = v ;
                aug = min(aug , edge[i].w) ;
                if(v == en)
                {
                    maxflow += aug ;
                    for(u = pre[v] ; ; u = pre[u])
                    {
                        edge[cur[u]].w -= aug ;
                        edge[cur[u]^1].w += aug ;
                        if(u == st)break;
                    }
                    aug = inf ;
                }
                break ;
            }
        }
        if(flag)continue ;
        int mi = n;
        for(int i=head[u];i!=-1;i=edge[i].next)
        {
            int v=edge[i].v;
            if(dis[v] < mi && edge[i].w > 0)
            {
                mi=dis[v];
                cur[u]=i;
            }
        }
        if((--gap[dis[u]]) == 0)break ;
        dis[u] = mi + 1 ;
        gap[dis[u]]++ ;
        u = pre[u] ;
    }
    return maxflow ;
}
int main()
{
   // freopen("in.txt" , "r" ,stdin) ;
    int t  ; int cas = 0 ;
    scanf("%d" , &t) ;
    while(t--)
    {
        scanf("%d%d" , &n , &m) ;
        int sum = 0 ;
        memset(head ,-1 , sizeof(head)) ;
        nedge = 0 ;
        int ma = 0 ;int mi = inf ;
        for(int i = 1;i <= n;i++)
        {
            int si , ei , pi ;
            scanf("%d%d%d" ,&pi , &si , &ei) ;
            addedge(st , i , pi) ;
            sum += pi ;
            for(int j = si;j <= ei ;j++)
            addedge(i , j + 500, 1) ;
        }
        for(int j = 501 ;j <= 1000;j++)
        addedge(j , en , m) ;
        int res ;int ans = 0 ;
        n = n + 2 + 500 ;
        ans = isap() ;
        printf("Case %d: ",++cas) ;
        if(ans >= sum)
        puts("Yes") ;
        else puts("No");
        puts("") ;
    }
    return  0 ;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-06 19:26:29

hdu3572Task Schedule 最大流的相关文章

hdu3572--Task Schedule(最大流+两种优化方法,dinic)

Task Schedule Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 3651    Accepted Submission(s): 1271 Problem Description Our geometry princess XMM has stoped her study in computational geometry t

HDU3572Task Schedule(最大流 ISAP比较快)建图方法不错

Task Schedule Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 5007    Accepted Submission(s): 1636 Problem Description Our geometry princess XMM has stoped her study in computational geometry t

hdu3572Task Schedule 最大流,判断满流 优化的SAP算法

PS:多校联赛的题目质量还是挺高的.建图不会啊,看了题解才会的. 参考博客:http://blog.csdn.net/luyuncheng/article/details/7944417 看了上面博客里的题解,思路就有了.不过建图还是有点麻烦.我把源点设为n+1 (不想从0开始,不修改模版),汇点就是n+2+MAX,其中MAX是题目中Ei的最大值. 这题,我有疑问:优化过的SAP算法的时间复杂度是O(m*n^2),此题的n最大为1000,m为50万,时间超过5亿了.1s的时限居然过了. 其中有个

hdu 3572 Task Schedule 最大流 Dinic算法,,卡时间。。建图非常有讲究

Task Schedule Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 4617    Accepted Submission(s): 1513 Problem Description Our geometry princess XMM has stoped her study in computational geometry t

HDU 3572 Task Schedule (最大流)

C - Task Schedule Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Practice HDU 3572 Description Our geometry princess XMM has stoped her study in computational geometry to concentrate on her newly opened fac

题单二:图论500

http://wenku.baidu.com/link?url=gETLFsWcgddEDRZ334EJOS7qCTab94qw5cor8Es0LINVaGMSgc9nIV-utRIDh--2UwRLvsvJ5tXFjbdpzbjygEdpGehim1i5BfzYgYWxJmu ==========  以下是最小生成树+并查集=========================[HDU]1213         How Many Tables        基础并查集★1272         小

图论五百题!

生死看淡不服就淦,这才是人生! =============================以下是最小生成树+并查集======================================[HDU]1213 How Many Tables 基础并查集★1272 小希的迷宫 基础并查集★1325&&poj1308 Is It A Tree? 基础并查集★1856 More is better 基础并查集★1102 Constructing Roads 基础最小生成树★1232 畅通工程 基

图论 500题——主要为hdu/poj/zoj

转自——http://blog.csdn.net/qwe20060514/article/details/8112550 =============================以下是最小生成树+并查集======================================[HDU]1213   How Many Tables   基础并查集★1272   小希的迷宫   基础并查集★1325&&poj1308  Is It A Tree?   基础并查集★1856   More i

图论精炼500题

忘了从哪转的了... =============================以下是最小生成树+并查集====================================== [HDU] 1213               How Many Tables                    基础并查集★ 1272               小希的迷宫                     基础并查集★ 1325&&poj1308    Is It A Tree?