【网络流】:poj1698,Alice's Chance

来源:互联网 发布:ubuntu重启网络管理 编辑:程序博客网 时间:2024/05/18 02:15




题目大意:爱丽丝要拍电影,有n部电影,规定爱丽丝每部电影在每个礼拜只有固定的几天可以拍电影,只可以拍前面w个礼拜,并且这部电影要拍d天,问爱丽丝能不能拍完所有的电影
第一行代表有多少组数据
对于每组数据第一行代表有n部电影
接下来2到n+1行,每行代表一个电影,每行9个数,前面7个数,1代表拍,0代表不拍,第8个数代表要拍几天,第9个数代表有几个礼拜时间拍


源点:0号点为源点;

week点:1到350(7*50)号点 分别表示50个星期的每一天;

film点:351到370号点 表示20个film;

汇点:371号点表示汇点。


源点到每个week点连一个边,容量为1;

每个film点到汇点连一个边,容量为d,表示该film需要拍摄的天数;

week点与film点之间如果有对应关系,则连一条边,容量为1。连边时注意代码的顺序:

while(--w>=0)            {                for(k=1;k<=7;k++)                {                    if(a[k]==1)                    {                        add_edge(w*7+k,350+j,1,0);                    }                }            }            /*            for(k=1;k<=7;k++)            {                if(a[k]==1)                {                    while(--w>=0)                    {                        add_edge(w*7+k,350+j,1,0);                    }                }            }            */



/* * Dinic algo for max flow * * This implementation assumes that #nodes, #edges, and capacity on each edge <= INT_MAX, * which means INT_MAX is the best approximation of INF on edge capacity. * The total amount of max flow computed can be up to LLONG_MAX (not defined in this file), * but each 'dfs' call in 'dinic' can return <= INT_MAX flow value. */#include <stdio.h>#include <stdlib.h>#include <limits.h>#include <string.h>#include <assert.h>#include <queue>#include <vector># include<iostream># include<cstring># include<map>#define N (380)       //==================make sure this is the total node number!#define M (N*N+4*N)typedef long long LL;using namespace std;struct edge{    int v, cap, next;};edge e[M];int head[N], level[N], cur[N];int num_of_edges;//When there are multiple test sets, you need to re-initialize before eachvoid dinic_init(void){    num_of_edges = 0;    memset(head, -1, sizeof(head));    return;}int add_edge(int u, int v, int c1, int c2){    int& i=num_of_edges;    assert(c1>=0 && c2>=0 && c1+c2>=0); // check for possibility of overflow    e[i].v = v;    e[i].cap = c1;    e[i].next = head[u];    head[u] = i++;    e[i].v = u;    e[i].cap = c2;    e[i].next = head[v];    head[v] = i++;    return i;}void print_graph(int n){    for (int u=0; u<n; u++)    {        printf("%d: ", u);        for (int i=head[u]; i>=0; i=e[i].next)        {            printf("%d(%d)", e[i].v, e[i].cap);        }        printf("\n");    }    return;}//Find all augmentation paths in the current level graph This is the recursive versionint dfs(int u, int t, int bn){    if (u == t) return bn;    int left = bn;    for (int i=head[u]; i>=0; i=e[i].next)    {        int v = e[i].v;        int c = e[i].cap;        if (c > 0 && level[u]+1 == level[v])        {            int flow = dfs(v, t, min(left, c));            if (flow > 0)            {                e[i].cap -= flow;                e[i^1].cap += flow;                cur[u] = v;                left -= flow;                if (!left) break;            }        }    }    if (left > 0) level[u] = 0;    return bn - left;}bool bfs(int s, int t){    memset(level, 0, sizeof(level));    level[s] = 1;    queue<int> q;    q.push(s);    while (!q.empty())    {        int u = q.front();        q.pop();        if (u == t) return true;        for (int i=head[u]; i>=0; i=e[i].next)        {            int v = e[i].v;            if (!level[v] && e[i].cap > 0)            {                level[v] = level[u]+1;                q.push(v);            }        }    }    return false;}LL dinic(int s, int t){    LL max_flow = 0;    while (bfs(s, t))    {        memcpy(cur, head, sizeof(head));        max_flow += dfs(s, t, INT_MAX);    }    return max_flow;}int upstream(int s, int n){    int cnt = 0;    vector<bool> visited(n);    queue<int> q;    visited[s] = true;    q.push(s);    while (!q.empty())    {        int u = q.front();        q.pop();        for (int i=head[u]; i>=0; i=e[i].next)        {            int v = e[i].v;            if (e[i].cap > 0 && !visited[v])            {                visited[v] = true;                q.push(v);                cnt++;            }        }    }    return cnt; // excluding s}int main(){    int t,n,i,j,k,a[8],d,w,sum;    cin>>t;    for(i=1;i<=t;i++)    {        dinic_init();        sum=0;        for(j=1;j<=350;j++)        {            add_edge(0,j,1,0);        }        cin>>n;        for(j=1;j<=n;j++)        {            memset(a,0,sizeof(a));            for(k=1;k<=7;k++)            {                cin>>a[k];            }            cin>>d>>w;            sum+=d;            while(--w>=0)            {                for(k=1;k<=7;k++)                {                    if(a[k]==1)                    {                        add_edge(w*7+k,350+j,1,0);                    }                }            }            /*            for(k=1;k<=7;k++)            {                if(a[k]==1)                {                    while(--w>=0)                    {                        add_edge(w*7+k,350+j,1,0);                    }                }            }            */            add_edge(350+j,371,d,0);        }        if(sum==dinic(0,371))        {            cout<<"Yes"<<endl;        }        else        {            cout<<"No"<<endl;        }    }    return 0;}


1 0
原创粉丝点击