您的位置:首页 > 其它

hdu 2883 kebab

2013-08-05 19:52 375 查看
题意:有n个顾客,每个顾客Si时间到达,会点ni个肉串,每个肉串用ti单位时间能烤好,这个顾客想要在Ei时间前得到肉串(包括Ei)。卖主每单位时间能烤M单位的肉串,问最后能否令所有的顾客满足。

思路:最大流判满流。先建立一个源点S和汇点T,从S向每个顾客连一条容量为ni*ti的边,再从每个顾客向每个时间段连一条容量为inf的边,最后从每个时间段向T连一条M*时间段长度的边,这样以后求一下最大流,如果等于Σni*ti,那么说明能满足所有顾客,否则不能。这里要注意的是,由于时间的范围很大, 所以不能直接向每一天添加边,把所有的时间排个序,然后计算一个时间段,每次向时间段添加边即可,还有题目说每个肉串可以分成k份在不同时间烤,这样的话只要把ni*ti看成一个量就行了。



代码:

#include <iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<vector>
#define inf 2139062143
#define Inf 0x3FFFFFFFFFFFFFFFLL
#define eps 1e-9
#define pi acos(-1.0)
using namespace std;
const int maxn=1000+10;
const int N=1000000+10;
struct Edge
{
    int from,to,cap,flow;
};
struct Query
{
    int S,ni,E,ti;
};
struct Dinic
{
    vector<Edge>edges;
    vector<int>G[maxn];
    bool vis[maxn];
    int d[maxn],cur[maxn];
    int n,m,s,t;
    void Init(int n)
    {
        for(int i=0;i<=n;++i) G[i].clear();
        edges.clear();
    }
    void AddEdges(int from,int to,int cap)
    {
        edges.push_back((Edge){from,to,cap,0});
        edges.push_back((Edge){to,from,0,0});
        m=edges.size();
        G[from].push_back(m-2);
        G[to].push_back(m-1);
    }
    bool BFS()
    {
        queue<int>q;
        memset(vis,0,sizeof(vis));
        vis[s]=true;
        d[s]=0;
        q.push(s);
        while(!q.empty())
        {
            int x=q.front();q.pop();
            for(int i=0;i<G[x].size();++i)
            {
                Edge e=edges[G[x][i]];
                if(!vis[e.to]&&e.cap>e.flow)
                {
                    d[e.to]=d[x]+1;
                    vis[e.to]=true;
                    q.push(e.to);
                }
            }
        }
        return vis[t];
    }
    int DFS(int x,int a)
    {
        if(x==t||a==0) return a;
        int flow=0,f;
        for(int & i=cur[x];i<G[x].size();++i)
        {
            Edge & e=edges[G[x][i]];
            if(d[e.to]==d[x]+1&&(f=DFS(e.to,min(a,e.cap-e.flow)))>0)
            {
                flow+=f;
                edges[G[x][i]].flow+=f;
                edges[G[x][i]^1].flow-=f;
                a-=f;
                if(a==0) break;
            }
        }
        return flow;
    }
    int Maxflow(int s,int t)
    {
        this->s=s;this->t=t;
        int flow=0;
        while(BFS())
        {
            memset(cur,0,sizeof(cur));
            flow+=DFS(s,inf);
        }
        return flow;
    }
}dinic;
Query query[300];
int convert
,dd[500],val[maxn];
int getCon(int sz)
{
    sort(dd+1,dd+sz);
    int u=1;
    int i=1,j=1;
    for(i=2;i<sz;++i)
    {
        if(dd[i]==dd[j]) continue;
        dd[++j]=dd[i];
    }
    for(i=1;i<j;++i)
    {
        convert[dd[i]]=u;
        val[u]=dd[i+1]-dd[i];
        u++;
    }
    convert[dd[i]]=u;
    val[u]=0;
    return u;
}
int main()
{
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    int n,m;
    while(~scanf("%d%d",&n,&m))
    {
        int sum=0;
        int sz=1;
        for(int i=1;i<=n;++i)
        {
            scanf("%d%d%d%d",&query[i].S,&query[i].ni,&query[i].E,&query[i].ti);
            sum+=query[i].ni*query[i].ti;
            dd[sz++]=query[i].S;
            dd[sz++]=query[i].E;
        }
        sz=getCon(sz);
        int N=n+sz+1;
        dinic.Init(N);
        for(int i=1;i<=n;++i)
        {
            dinic.AddEdges(0,i,query[i].ni*query[i].ti);
            int t=convert[query[i].S];
            while(t!=convert[query[i].E])
            {
                dinic.AddEdges(i,n+t,inf);
                t++;
            }
        }
        for(int i=1;i<sz;++i)
            dinic.AddEdges(n+i,N,m*val[i]);
        int res=dinic.Maxflow(0,N);
        if(res==sum)
           printf("Yes\n");
        else
           printf("No\n");
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: