您的位置:首页 > 其它

hdu3572Task Schedule 最大流

2015-08-10 20:58 232 查看
//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 ;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: