poj-1698-Alice's Chance

来源:互联网 发布:大数据分析报告案例 编辑:程序博客网 时间:2024/05/01 01:43

这道题主要难点是构图,想了半天也想不懂怎么构图,后来在网上找了一下别人的题解

构图:把每个电影需要的星期数都拆开,变成一条线的权值设为1,这样每个星期中的某一天只能被一部电影占据,源点直接连接到电影,权值为需要的天数,之后将日期和汇点相连,比如有一部电影需要4周,就需要有4*7=28个点和汇点相连!

把图画出来就直接用dinic算法就行了
Dinic算法的原理与构造

#include <iostream>#include <cstdio>#include <cstring>#define ll long long #define N 400 const int INF = 0x3f3f3f3f;using namespace std;struct Edge{    int v, f;    int next;}edge[N*N];int n, first[N], cnt, q[N], F[22][8], level[N];void Init(){    cnt = 0;    memset(first, -1, sizeof(first));}void read(int u, int v, int f){    edge[cnt].v = v;    edge[cnt].f = f;    edge[cnt].next = first[u];    first[u] = cnt++;    edge[cnt].v = u;    edge[cnt].f = 0;    edge[cnt].next = first[v];    first[v] = cnt++;}bool bfs(int s, int t){    memset(level, 0, sizeof(level));    level[s] = 1;    int rear = 0, front = 0;    q[front++] = s;    while(rear < front){        int x = q[rear++];        if (x == t) return true;        for (int e = first[x]; e != -1; e = edge[e].next){            int v = edge[e].v;            int f = edge[e].f;            if (!level[v] && f){                level[v] = level[x]+1;                q[front++] = v;            }        }    }    return false;}int Dinic(int s, int t){    int ans = 0;    while(bfs(s, t)){        int e, x, y, back, iter = 1;        while(iter){            x = (iter==1)?s:edge[q[iter-1]].v;            if (x == t){                int minCap = INF;                for (int i = 1; i < iter; i++){                    e = q[i];                    if (edge[e].f < minCap){                        minCap = edge[e].f;                        back = i;                    }                }                for (int i = 1; i < iter; i++){                    e = q[i];                    edge[e].f -= minCap;                    edge[e^1].f += minCap;                }                ans += minCap;                iter = back;            }else{                for (e = first[x]; e != -1; e = edge[e].next){                    y = edge[e].v;                    if (edge[e].f && level[y] == level[x]+1){                        break;                    }                }                if (e != -1){                    q[iter++] = e;                }                else{                    level[x] = -1;                    iter--;                }            }        }    }    return ans;}int main(){#ifndef ONLINE_JUDGE    freopen("1.txt", "r", stdin);#endif    int i, j, k, T, d, w, sum, flag;    scanf("%d", &T);    while(T--){        sum = 0;        flag = 0;        Init();        scanf("%d", &n);        for (i = 1; i <= n; i++){            for (j = 1; j <= 7; j++){                scanf("%d", &F[i][j]);            }            scanf("%d%d", &d, &w);            read(0, i, d);            sum += d;            flag = max(flag, w);            for (k = 0; k < w; k++){                for (j = 1; j <= 7; j++){                    if (F[i][j]){                        read(i, 7*k+j+n, 1);                    }                }            }        }        int tmp = n+7*flag+1;        for (i = 0; i < flag; i++){            for (j = 1; j <= 7; j++){                read(7*i+n+j, tmp, 1);            }        }        int ans = Dinic(0, tmp);        if (sum == ans){            puts("Yes");        }else{            puts("No");        }    }    return 0;}
0 0