hdu 3572(最大流)

来源:互联网 发布:网络推广加盟 编辑:程序博客网 时间:2024/05/01 21:44

                                           Task Schedule

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 6590    Accepted Submission(s): 2058


Problem Description
Our geometry princess XMM has stoped her study in computational geometry to concentrate on her newly opened factory. Her factory has introduced M new machines in order to process the coming N tasks. For the i-th task, the factory has to start processing it at or after day Si, process it for Pi days, and finish the task before or at day Ei. A machine can only work on one task at a time, and each task can be processed by at most one machine at a time. However, a task can be interrupted and processed on different machines on different days.
Now she wonders whether he has a feasible schedule to finish all the tasks in time. She turns to you for help.
 

Input
On the first line comes an integer T(T<=20), indicating the number of test cases.

You are given two integer N(N<=500) and M(M<=200) on the first line of each test case. Then on each of next N lines are three integers Pi, Si and Ei (1<=Pi, Si, Ei<=500), which have the meaning described in the description. It is guaranteed that in a feasible schedule every task that can be finished will be done before or at its end day.
 

Output
For each test case, print “Case x: ” first, where x is the case number. If there exists a feasible schedule to finish all the tasks, print “Yes”, otherwise print “No”.

Print a blank line after each test case.
 

Sample Input
24 31 3 5 1 1 42 3 73 5 92 22 1 31 2 2
 

Sample Output
Case 1: Yes Case 2: Yes
题目链接: 点击打开链接
题意:有n个任务,m台机器,每个任务如下描述:pi,si,ei,表示【si,ei] 这个时间段内,要做pi天,才能把任务做完(每个任务在同一个时间段只能由一台机器做)。问是否能完成所有任务。
思路:
 想到最大流还是不太容易的。最大流最为关键的是构图。
构建一个虚拟起点和虚拟汇点,起点和每个任务相连,流量为做这个任务所需要的时间,每天定义成一个点,与终点相连,流量为机器数,每个任务与可以做这个任务的时间相连,流量为1,;
易错点:
1.题目带来的坑点,第一个数为做这个任务要做时间长度,后两个数是区间长度,坑死我了这个。
2.这里的输出要有两个换行,要不然会present error;
3.dinic 算法会超时,sap才能过。


代码:

超时代码:
#include<stdio.h>#include<string.h>#include<algorithm>#include<queue>using namespace std;const int maxn=503; const int Ni = 2100; const int MAX = 1<<26; struct Edge{     int u,v,c;     int next; }edge[20*Ni]; int n,m; int edn;//边数 int p[Ni];//父亲 int d[Ni],vis[maxn]; int sp,tp;//原点,汇点 void addedge(int u,int v,int c) {     edge[edn].u=u; edge[edn].v=v; edge[edn].c=c;     edge[edn].next=p[u]; p[u]=edn++;     edge[edn].u=v; edge[edn].v=u; edge[edn].c=0;     edge[edn].next=p[v]; p[v]=edn++; } int bfs() {     queue <int> q;     memset(d,-1,sizeof(d));     d[sp]=0;     q.push(sp);     while(!q.empty())     {         int cur=q.front();         q.pop();         for(int i=p[cur];i!=-1;i=edge[i].next)         {             int u=edge[i].v;             if(d[u]==-1 && edge[i].c>0)             {                 d[u]=d[cur]+1;                 q.push(u);             }         }     }     return d[tp] != -1; } int dfs(int a,int b) {     int r=0;     if(a==tp)return b;     for(int i=p[a];i!=-1 && r<b;i=edge[i].next)     {         int u=edge[i].v;         if(edge[i].c>0 && d[u]==d[a]+1)         {             int x=min(edge[i].c,b-r);             x=dfs(u,x);             r+=x;             edge[i].c-=x;             edge[i^1].c+=x;         }     }     if(!r)d[a]=-2;     return r; } int dinic(int sp,int tp) {     int total=0,t;     while(bfs())     {         while(t=dfs(sp,MAX))         total+=t;     }     return total; }int main(){    int T;    while(scanf("%d",&T)!=EOF)    for(int t=1;t<=T;t++)    {        int n,m;        int a,b,c;         edn=0;//初始化        memset(p,-1,sizeof(p));        scanf("%d%d",&n,&m);        sp=maxn+1,tp=maxn+2;        int sum=0;        for(int i=0;i<n;i++)        {            scanf("%d%d%d",&b,&a,&c);            sum+=b;            addedge(sp,1000+i,b);            for(int j=a;j<=c;j++)            {               addedge(1000+i,j,1);               vis[j]=1;            }        }        for(int j=0;j<maxn;j++)        if(vis[j])          addedge(j,tp,m);        printf("Case %d: ",t);        if(dinic(sp,tp)==sum)            printf("Yes\n\n");        else            printf("No\n\n");    }    return 0;}

sap代码;
#include<stdio.h>#include<string.h>#include<algorithm>#include<queue>using namespace std;const int MAXN=20010;//点数的最大值const int MAXM=880010;//边数的最大值const int INF=0x7fffffff;const int maxn=503;int vis[maxn];struct Node{    int from,to,next;    int cap;}edge[MAXM];int tol;int head[MAXN];int dep[MAXN];int gap[MAXN];//gap[x]=y :说明残留网络中dep[i]==x的个数为yint n;//n是总的点的个数,包括源点和汇点void init(){    tol=0;    memset(head,-1,sizeof(head));}void addedge(int u,int v,int w){    edge[tol].from=u;    edge[tol].to=v;    edge[tol].cap=w;    edge[tol].next=head[u];    head[u]=tol++;    edge[tol].from=v;    edge[tol].to=u;    edge[tol].cap=0;    edge[tol].next=head[v];    head[v]=tol++;}void BFS(int start,int end){    memset(dep,-1,sizeof(dep));    memset(gap,0,sizeof(gap));    gap[0]=1;    int que[MAXN];    int front,rear;    front=rear=0;    dep[end]=0;    que[rear++]=end;    while(front!=rear)    {        int u=que[front++];        if(front==MAXN)front=0;        for(int i=head[u];i!=-1;i=edge[i].next)        {            int v=edge[i].to;            if(dep[v]!=-1)continue;            que[rear++]=v;            if(rear==MAXN)rear=0;            dep[v]=dep[u]+1;            ++gap[dep[v]];        }    }}int SAP(int start,int end){    int res=0;    BFS(start,end);    int cur[MAXN];    int S[MAXN];    int top=0;    memcpy(cur,head,sizeof(head));    int u=start;    int i;    while(dep[start]<n)    {        if(u==end)        {            int temp=INF;            int inser;            for(i=0;i<top;i++)               if(temp>edge[S[i]].cap)               {                   temp=edge[S[i]].cap;                   inser=i;               }            for(i=0;i<top;i++)            {                edge[S[i]].cap-=temp;                edge[S[i]^1].cap+=temp;            }            res+=temp;            top=inser;            u=edge[S[top]].from;        }        if(u!=end&&gap[dep[u]-1]==0)//出现断层,无增广路          break;        for(i=cur[u];i!=-1;i=edge[i].next)           if(edge[i].cap!=0&&dep[u]==dep[edge[i].to]+1)             break;        if(i!=-1)        {            cur[u]=i;            S[top++]=i;            u=edge[i].to;        }        else        {            int min=n;            for(i=head[u];i!=-1;i=edge[i].next)            {                if(edge[i].cap==0)continue;                if(min>dep[edge[i].to])                {                    min=dep[edge[i].to];                    cur[u]=i;                }            }            --gap[dep[u]];            dep[u]=min+1;            ++gap[dep[u]];            if(u!=start)u=edge[S[--top]].from;        }    }    return res;}int main(){    int T;    scanf("%d",&T);    for(int t=1;t<=T;t++)    {        init();        int n1,m;        int a,b,c;        scanf("%d%d",&n1,&m);        int sp=maxn+1,tp=maxn+2;        int sum=0;        memset(vis,0,sizeof(vis));        n=0;        for(int i=0;i<n1;i++)        {            scanf("%d%d%d",&b,&a,&c);            sum+=b;            addedge(sp,1000+i,b);            for(int j=a;j<=c;j++)            {               addedge(1000+i,j,1);               if(!vis[j])                n++;                vis[j]=1;            }        }        printf("Case %d: ",t);        for(int j=0;j<maxn;j++)        if(vis[j])          addedge(j,tp,m);        n+=n1;        n+=2;        if(SAP(sp,tp)==sum)            printf("Yes\n\n");        else            printf("No\n\n");    }    return 0;}




1 0
原创粉丝点击