HDU3572 Task Schedule (maximum flow + patterned thinking)

Meaning of the questions:

There are machines M of N tasks, each task i to the time it takes to complete each task to start and Pi at the first day Si, Ei days before the end of the first, to ensure that task must be completed between the (S, E) .

Each machine in one day only run one task, a task can be replaced in the middle of the machine to continue to ask is there a way to arrange a time so that all tasks are completed.

(The first time to see it is the maximum flow ah !!)

Ideas:

After this analysis may want to set up a super source point S = 0, S and let each task i establish two-way side S-> i, a weight of Pi, and then let each task to each day d (d is the Si to Ei every day)

Establish two-way edge i-> d, the weight is 1 (every day because the machine can only run one task), and then let d every day to build a two-way side d- super Meeting Point T> T, weight is M (because from open task

To start all tasks are completed, there will be up to the day d M of the machine running, that is up to the task of M going on). Then ran maximum flow, and if the maximum flow maxflow sigma (Pi) the same,

Then the output "Yes", else output "No".

! ! ! Notably, the number of days and make the task i d as a bipartite graph, (because of possible tasks i and j may be connected to a task side, because all [Si, Ei] interval may contain certain tasks subscript)

That means putting the task number or serial number of days to map, my code is to be mapped to the number of days d d + n.

#include <bits/stdc++.h>
using namespace std;

const int maxn = 500 + 5;
const int inf = 0x3f3f3f3f;     //INF
const int ainf = 0xcfcfcfcf;    //-INF
int n, m, T, d[maxn*2], s, t, maxflow;
int head[maxn*2], tot, sum;
struct edge{
    int to, w, next;
} ed[maxn*maxn*2+maxn*4];
//The edge connected to the node number of days for the boundary n * n, bi + 2 by the super source node to the task even super + bidirectional edges and sink nodes of days = the number of edges connected bidirectional task node side. 
inline void the Add ( int U, int V, int W) { 
    ED [ ++ TOT] .to = V; ED [TOT] .W = W; ED [TOT] head .next = [U]; head [U] = TOT; 
    ED [ ++ TOT] .to = U; ED [TOT] .W = 0 ; ED [TOT] = .next head [V]; head [V] = TOT; 
} 

inline BOOL BFS () { 
    Queue < int > Q; 
    Memset (D, 0 , the sizeof (D)); 
    D [S] = . 1 ; 
    q.push (S); 
    the while( !q.empty() ){
        int x = q.front();
        q.pop();
        for( int i=head[x]; i!=-1; i=ed[i].next ){
            int y = ed[i].to;
            if( ed[i].w && !d[y] ){
                d[y] = d[x] + 1;
                q.push(y);
                if( y==t ) return 1;
            }
        }
    }
    return 0;
}

inline int min( int a, int b ){
    return a<b ?a:b;
}

inline int max( int a, int b ){
    return a>b? a:b;
}

inline int dfs( int x, int flow ){
    if(x==t) return flow;
    int res = flow, k;
    for( int i=head[x]; i!=-1 && res; i=ed[i].next ){
        int y = ed[i].to;
        if( ed[i].w && d[y]==d[x]+1 ){
            k = dfs(y, min(res, ed[i].w) );
            if(!k) d[y] = 0;
            ed[i].w -= k;
            ed[i^1].w += k;
            res -= k;
        }
    }
    return flow-res;
}

inline void dinic(){
    int flow = maxflow = 0;
    while( bfs() )
        while( flow=dfs(s, inf) ) maxflow += flow;
}

int main(){
    // freopen("in.txt", "r", stdin);
    scanf("%d", &T);
    for( int k=1; k<=T; k++ ){
        memset( head, -1, sizeof(head) );
        tot = 1; sum = 0;
        scanf("%d%d", &n, &m);
        s = 0;
        int l = inf, r = ainf;          //ainf==0xcfcfcfcf 即-INF
        for( int i=1; I <= n-; I ++ ) {
             int A, B, P; 
            Scanf ( " % D% D% D " , & P, & A, & B); 
            L = min (A, L);             // find the number of days of lower bound 
            R & lt = max (B, R & lt);             // find the upper limit of the number of days 
            the Add (S, i, P);              // super source node and the task i even edge 
            for ( int   J = a; J <= B; J ++) the Add (I, J + n-, . 1 );         // task mapping nice even number days edges 
            SUM = P +;            // Sigma (Pi) 
        } 
        T = n-R & lt + + . 1 ;              // super meeting point may be chosen to allow universal t 2 * maxn-1, is nothing different 
        for ( int I = L; I <= R & lt; I ++) the Add (n-I +, t, m);      // super sink to days t even edge 
        Dinic (); 
        the printf ( " Case% D: " , K);
         IF (MaxFlow == SUM) the puts ( " Yes \ n- " );        // the puts () comes line feed, and then plus a \ n to control the output format of 
        the else the puts ( " No \ n " ); 
    } 

    return  0 ; 
}

 

Guess you like

Origin www.cnblogs.com/WAautomaton/p/10974429.html