程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> POJ 1698 Alice's Chance 網絡流(水

POJ 1698 Alice's Chance 網絡流(水

編輯:C++入門知識

POJ 1698 Alice's Chance 網絡流(水


 

題目大意: 有個人想拍n部電影,每部電影限定每周哪幾天可以拍

並且必須在第ki周之前把這部電影拍完,問能否拍完n部電影

解題思路: 把每部電影當作一個頂點,源點指向這些頂點,容量為該電影需要拍多少天

然後把每一天都當作頂點,某個工作可以在這天完成就連容量為1大邊

每天的頂點指向匯點,容量也為1

最後求出最大流,滿流則說明可以完成這些工作


 

啦啦啦

 

#include 
#include 
#include 
#include 
template 
inline bool rd(T &ret) {
    char c; int sgn;
    if(c=getchar(),c==EOF) return 0;
    while(c!='-'&&(c<'0'||c>'9')) c=getchar();
    sgn=(c=='-')?-1:1;
    ret=(c=='-')?0:(c-'0');
    while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0');
    ret*=sgn;
    return 1;
}
template 
inline void pt(T x) {
    if (x <0) {
        putchar('-');
        x = -x;
    }
    if(x>9) pt(x/10);
    putchar(x%10+'0');
}
using namespace std;
//點標 [0,n]
const int N = 20+50*7+100;
const int M = 500010;
const int INF = ~0u >> 2;
template
struct Max_Flow {
    int n;
    int Q[N], sign;
    int head[N], level[N], cur[N], pre[N];
    int nxt[M], pnt[M], E;
    T cap[M];
    void Init(int n) {
        this->n = n+1;
        E = 0;
        std::fill(head, head + this->n, -1);
    }
    //有向rw 就= 0
    void add(int from, int to, T c) {
        pnt[E] = to;
        cap[E] = c;
        nxt[E] = head[from];
        head[from] = E++;

        pnt[E] = from;
        cap[E] = 0;
        nxt[E] = head[to];
        head[to] = E++;
    }
    bool Bfs(int s, int t) {
        sign = t;
        std::fill(level, level + n, -1);
        int *front = Q, *tail = Q;
        *tail++ = t; level[t] = 0;
        while(front < tail && level[s] == -1) {
            int u = *front++;
            for(int e = head[u]; e != -1; e = nxt[e]) {
                if(cap[e ^ 1] > 0 && level[pnt[e]] < 0) {
                    level[pnt[e]] = level[u] + 1;
                    *tail ++ = pnt[e];
                }
            }
        }
        return level[s] != -1;
    }
    void Push(int t, T &flow) {
        T mi = INF;
        int p = pre[t];
        for(int p = pre[t]; p != -1; p = pre[pnt[p ^ 1]]) {
            mi = std::min(mi, cap[p]);
        }
        for(int p = pre[t]; p != -1; p = pre[pnt[p ^ 1]]) {
            cap[p] -= mi;
            if(!cap[p]) {
                sign = pnt[p ^ 1];
            }
            cap[p ^ 1] += mi;
        }
        flow += mi;
    }
    void Dfs(int u, int t, T &flow) {
        if(u == t) {
            Push(t, flow);
            return ;
        }
        for(int &e = cur[u]; e != -1; e = nxt[e]) {
            if(cap[e] > 0 && level[u] - 1 == level[pnt[e]]) {
                pre[pnt[e]] = e;
                Dfs(pnt[e], t, flow);
                if(level[sign] > level[u]) {
                    return ;
                }
                sign = t;
            }
        }
    }
    T Dinic(int s, int t) {
        pre[s] = -1;
        T flow = 0;
        while(Bfs(s, t)) {
            std::copy(head, head + n, cur);
            Dfs(s, t, flow);
        }
        return flow;
    }
};
Max_Flow F;
int n;
void work(){
    rd(n);
    int from = 0, to = n + 50*7 +1;
    F.Init(to);
    int all = 0;
    for(int i = 1, d, w; i <= n; i++)
    {
        int a[8];
        for(int j = 1; j <= 7; j++)rd(a[j]);
        rd(d); rd(w);
        all += d;
        F.add(from, i, d);
        for(int week = 0; week < w; week++)
            for(int j = 1; j <= 7; j++)
                if(a[j])
                    F.add(i, n+week*7+j, 1);
    }
    for(int i = 0; i < 50; i++)
        for(int j = 1; j <= 7; j++)
            F.add(n+i*7+j, to, 1);
    all == F.Dinic(from, to)?puts(Yes):puts(No);
}
int main(){
    int T; rd(T);
    while(T--)
        work();
    return 0;
}


 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved