首页 > 代码库 > HDU 3572 Task Schedule (最大流)

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 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台机器,每个任务有三个值,s e p表示这个完成这个任务需要p天,并且这p天要在s到e这段时间完成(包括s和e),任务可以中断再换台机器换一天来继续做,每台机器每天只能完成一个任务,而且一个任务每天只能给一台机器来做
 
思路:最大流。建图方法是, 把每个任务当成一个点,每个时间点也当成一个点,源点连接每个任务容量为p,每个任务连接每个时间点容量为1,每个时间点连接汇点容量为m,然后判断最大流是否和p点总和相等
 
妈蛋啊,这题卡了不少天,还以为是各种模板错了,原来所因为给每个时间点连汇点点时候for循环用i但是下面却用了j我擦擦擦卡勒那么多天,都换了几个模板来做了。。
 
AC代码:  1.白书dinic模板  2.白书ISAP模板 3.网上的dinic模板  4.网上ISAP模板
1和2跑了350ms  3跑了78ms 4跑了109ms
 
1.  359ms
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <vector>#include <queue>using namespace std;typedef long long ll;typedef pair<int,int> pii;const int INF = 1e9;const double eps = 1e-6;const int maxn = 1010;int cas = 1;struct Edge{    int from,to,cap,flow;    Edge() {}    Edge(int a,int b,int c,int d)    {        from=a,to=b,cap=c,flow=d;    }};struct Dinic{    int n,m,s,t;    vector<Edge> edges;    vector<int> G[maxn];    bool vis[maxn];    int d[maxn];    int cur[maxn];    void AddEdge(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);    }    void init(int x)    {        memset(d,0,sizeof(d));        edges.clear();        for(int i=0;i<=x;i++)            G[i].clear();    }    bool BFS()    {        memset(vis,0,sizeof(vis));        queue<int> Q;        Q.push(s);        d[s]=0;        vis[s]=1;        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)                {                    vis[e.to]=1;                    d[e.to]=d[x]+1;                    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[x]+1==d[e.to] && (f=DFS(e.to,min(a,e.cap-e.flow)))>0)            {                e.flow += f;                edges[G[x][i]^1].flow -= f;                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 dinic;int n,m;inline int id_task(int x)  {return x;}inline int id_time(int x)  {return x+500;}int s = 0, t = 1001;void run(){    scanf("%d%d",&n,&m);    dinic.init(1001);    int i,j;    int a,b,c;    int sum=0;    for(i=1;i<=n;i++)    {        scanf("%d%d%d",&c,&a,&b);        sum+=c;        dinic.AddEdge(s,id_task(i),c);        for(j=a;j<=b;j++)            dinic.AddEdge(id_task(i),id_time(j),1);    }    for(i=1;i<=500;i++)        dinic.AddEdge(id_time(i),t,m);//    printf("%d\n",dinic.Maxflow(0,500+500+1));    printf("Case %d: %s\n\n",cas++,dinic.Maxflow(s,t)==sum?"Yes":"No");}int main(){    #ifdef LOCAL    freopen("in","r",stdin);    #endif    int _;    scanf("%d",&_);    while(_--)        run();    return 0;}
View Code

 

2.  343ms

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <vector>#include <queue>#define FOR(i,n) for(i=0;i<=(n);i++)using namespace std;typedef long long ll;typedef pair<int,int> pii;const int INF = 1e9;const double eps = 1e-6;const int maxn = 1010;const int N = 1010;int cas = 1;struct Edge{    int from,to,cap,flow;    Edge() {}    Edge(int a,int b,int c,int d)    {        from=a,to=b,cap=c,flow=d;    }};struct ISAP{    int n,m,s,t;    int p[N],num[N];    vector<Edge> edges;    vector<int> G[N];    bool vis[N];    int d[N],cur[N];    void init(int _n)    {        n=_n;        int i;        edges.clear();        FOR(i,n)        {            G[i].clear();            d[i]=INF;        }    }    void AddEdge(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()    {        memset(vis,0,sizeof(vis));        queue<int> Q;        Q.push(t);        d[t]=0;        vis[t]=1;        while(!Q.empty())        {            int x = Q.front(); Q.pop();            for(unsigned i=0;i<G[x].size();i++)            {                Edge& e = edges[G[x][i]^1];                if(!vis[e.from] && e.cap>e.flow)                {                    vis[e.from]=1;                    d[e.from] = d[x]+1;                    Q.push(e.from);                }            }        }        return vis[s];    }    int Augment()    {        int x=t, a=INF;        while(x!=s)        {            Edge& e = edges[p[x]];            a = min(a,e.cap-e.flow);            x = edges[p[x]].from;        }        x = t;        while(x!=s)        {            edges[p[x]].flow+=a;            edges[p[x]^1].flow-=a;            x=edges[p[x]].from;        }        return a;    }    int Maxflow(int _s,int _t)    {        s=_s; t=_t;        int flow = 0, i;        BFS();        if(d[s]>=n) return 0;        memset(num,0,sizeof(num));        memset(p,0,sizeof(p));        FOR(i,n) if(d[i]<INF) num[d[i]]++;        int x=s;        memset(cur,0,sizeof(cur));        while(d[s]<n)        {            if(x==t)            {                flow+=Augment();                x=s;            }            int ok=0;            for(unsigned i=cur[x];i<G[x].size();i++)            {                Edge& e=edges[G[x][i]];                if(e.cap>e.flow && d[x]==d[e.to]+1)                {                    ok=1;                    p[e.to]=G[x][i];                    cur[x]=i;                    x=e.to;                    break;                }            }            if(!ok)            {                int m=n-1;                for(unsigned i=0;i<G[x].size();i++)                {                    Edge& e=edges[G[x][i]];                    if(e.cap>e.flow) m=min(m,d[e.to]);                }                if(--num[d[x]]==0) break;                num[d[x]=m+1]++;                cur[x]=0;                if(x!=s) x=edges[p[x]].from;            }        }        return flow;    }};ISAP dinic;int n,m;inline int id_task(int x)  {return x;}inline int id_time(int x)  {return x+500;}int s = 0, t = 1001;void run(){    scanf("%d%d",&n,&m);    dinic.init(1001);    int i,j;    int a,b,c;    int sum=0;    for(i=1;i<=n;i++)    {        scanf("%d%d%d",&c,&a,&b);        sum+=c;        dinic.AddEdge(s,id_task(i),c);        for(j=a;j<=b;j++)            dinic.AddEdge(id_task(i),id_time(j),1);    }    for(i=1;i<=500;i++)        dinic.AddEdge(id_time(i),t,m);//    printf("%d\n",dinic.Maxflow(0,500+500+1));    printf("Case %d: %s\n\n",cas++,dinic.Maxflow(s,t)==sum?"Yes":"No");}int main(){    #ifdef LOCAL    freopen("in","r",stdin);    #endif    int _;    scanf("%d",&_);    while(_--)        run();    return 0;}
View Code

 

3.  78ms

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <vector>#include <queue>#define FOR(i,n) for(i=0;i<=(n);i++)using namespace std;typedef long long ll;typedef pair<int,int> pii;const int INF = 0xfffffff;const double eps = 1e-6;const int N = 1010;int cas = 1;const int maxn=1010;const int maxm=500010;struct edge{    int v,next,val;} G[maxm];int s = 0, t = 1001;struct Dinic{    int pre[maxn],idx, sum;    int N,M;    int level[maxn];    int gap[maxn];    void add_edge(int from,int to,int val)    {        G[idx].v=to;        G[idx].val=val;        G[idx].next=pre[from];        pre[from]=idx++;        G[idx].v=from;        G[idx].val=0;        G[idx].next=pre[to];        pre[to]=idx++;    }    int dfs(int pos,int cost, int cnt)    {        if (pos==t)        {            return cost;        }        int j,minh=cnt-1,lv=cost,d;        for (j=pre[pos];j!=-1;j=G[j].next)        {            int v=G[j].v,val=G[j].val;            if(val>0)            {                if (level[v]+1==level[pos])                {                    if (lv<G[j].val) d=lv;                    else d=G[j].val;                    d=dfs(v,d,cnt);                    G[j].val-=d;                    G[j^1].val+=d;                    lv-=d;                    if (level[s]>=cnt) return cost-lv;                    if (lv==0) break;                }                if (level[v]<minh)    minh=level[v];            }        }        if (lv==cost)        {            --gap[level[pos]];            if (gap[level[pos]]==0) level[s]=cnt;            level[pos]=minh+1;            ++gap[level[pos]];        }        return cost-lv;    }    int Maxflow(int s,int t, int cnt)    {        int flow=0;        gap[s]=cnt;        while (level[s]<cnt)        {//            int t=dfs(s,INF,cnt);            flow+=dfs(s,INF, cnt);//            flow+=t;//            cout<<flow<<endl;        }        return flow;    }    void init()    {        memset(pre, -1, sizeof(pre));        memset(gap,0,sizeof(gap));        memset(level,0,sizeof(level));        sum = idx = 0;    }};Dinic dinic;int n,m;inline int id_task(int x)  {return x;}inline int id_time(int x)  {return x+500;}void run(){    scanf("%d%d",&n,&m);    dinic.init();    int i,j;    int a,b,c;    int sum=0;    for(i=1;i<=n;i++)    {        scanf("%d%d%d",&c,&a,&b);        sum+=c;        dinic.add_edge(s,id_task(i),c);        for(j=a;j<=b;j++)            dinic.add_edge(id_task(i),id_time(j),1);    }    for(i=1;i<=500;i++)        dinic.add_edge(id_time(i),t,m);//    printf("%d\n",dinic.Maxflow(0,500+500+1));    printf("Case %d: %s\n\n",cas++,dinic.Maxflow(s,t,t+1)==sum?"Yes":"No");}int main(){    #ifdef LOCAL    freopen("in","r",stdin);    #endif    int _;    scanf("%d",&_);    while(_--)        run();    return 0;}
View Code

 

4.109ms

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <vector>#include <queue>#define FOR(i,n) for(i=0;i<=(n);i++)using namespace std;typedef long long ll;typedef pair<int,int> pii;const int INF = 1e9;const double eps = 1e-6;const int maxn = 1010;const int N = 1010;int cas = 1;const int inf = 0x3fffffff;template <int N, int M>struct Isap{    int top;    int d[N], pre[N], cur[N], gap[N];    struct Vertex{        int head;    } V[N];    struct Edge{        int v, next;        int c, f;    } E[M];    void init(){        memset(V, -1, sizeof(V));        top = 0;    }    void add_edge(int u, int v, int c){        E[top].v = v;        E[top].c = c;        E[top].f = 0;        E[top].next = V[u].head;        V[u].head = top++;    }    void add(int u,int v, int c){        add_edge(u, v, c);        add_edge(v, u, 0);    }    void set_d(int t){        queue<int> Q;        memset(d, -1, sizeof(d));        memset(gap, 0, sizeof(gap));        d[t] = 0;        Q.push(t);        while(!Q.empty()) {            int v = Q.front(); Q.pop();            ++gap[d[v]];            for(int i = V[v].head; ~i; i = E[i].next) {                int u = E[i].v;                if(d[u] == -1) {                    d[u] = d[v] + 1;                    Q.push(u);                }            }        }    }    int sap(int s, int t, int num) {        set_d(t);        int ans = 0, u = s;        int flow = inf;        memcpy(cur, V, sizeof(V));        while(d[s] < num) {            int &i = cur[u];            for(; ~i; i = E[i].next) {                int v = E[i].v;                if(E[i].c > E[i].f && d[u] == d[v] + 1) {                    u = v;                    pre[v] = i;                    flow = min(flow, E[i].c - E[i].f);                    if(u == t) {                        while(u != s) {                            int j = pre[u];                            E[j].f += flow;                            E[j^1].f -= flow;                            u = E[j^1].v;                        }                        ans += flow;                        flow = inf;                    }                    break;                }            }            if(i == -1) {                if(--gap[d[u]] == 0)                    break;                int dmin = num - 1;                cur[u] = V[u].head;                for(int j = V[u].head; ~j; j = E[j].next)                    if(E[j].c > E[j].f)                        dmin = min(dmin, d[E[j].v]);                d[u] = dmin + 1;                ++gap[d[u]];                if(u != s)                    u = E[pre[u] ^ 1].v;            }        }        return ans;    }};Isap<1010, 1000000> Sap;//调用方式://Sap.init(); //建边前调用//Sap.add(u, v, c); //在u->v之间建一条容量为c的边//Sap.sap(s, t, num); //s为源点,t为汇点,num为边的数量int n,m;inline int id_task(int x)  {return x;}inline int id_time(int x)  {return x+500;}int s = 0, t = 1001;void run(){    scanf("%d%d",&n,&m);    Sap.init();    int i,j;    int a,b,c;    int sum=0;    for(i=1;i<=n;i++)    {        scanf("%d%d%d",&c,&a,&b);        sum+=c;        Sap.add(s,id_task(i),c);        for(j=a;j<=b;j++)            Sap.add(id_task(i),id_time(j),1);    }    for(i=1;i<=500;i++)        Sap.add(id_time(i),t,m);//    printf("%d\n",Sap.sap(s,t,t+100));    printf("Case %d: %s\n\n",cas++,Sap.sap(s,t,t+1)==sum?"Yes":"No");}int main(){    #ifdef LOCAL    freopen("in","r",stdin);    #endif    int _;    scanf("%d",&_);    while(_--)        run();    return 0;}
View Code

 

 
 
 
 
 

HDU 3572 Task Schedule (最大流)