• poj1698 [ Usaco2007 Feb ] --最大流(Dinic)


    题目大意:

          爱丽丝要拍电影,有n部电影,规定爱丽丝每天只能拍一部电影,每部电影在每个礼拜只有固定的几天可以拍电影,只可以拍前面w个礼拜,并且这部电影要拍d天,问爱丽丝能不能拍完所有的电影。

    思路:

          建图。点1~350代表天数(因为最多只有350天),点351~370代表电影(最多只有20部电影)。从源点向每部电影连一条容量为d的边,从每部电影向可以拍摄它的那几天连一条容量为1的边,从每天向汇点连一条容量为1的边(限制每天只能拍一部电影)。再求一遍最大流,看其是否与sum(d[i])相等,如果是,就输出Yes,否则输出No。

    具体看代码。

    #include<iostream>
    #include<cstdio>
    #include<vector>
    #include<queue>
    #include<cstring>
    using namespace std;
    #define INF 2147483647
    vector<int>g[400];
    queue<int>q;
    struct Edge{
        int to,from,cap,flow;
    }edge[160000];
    int i,j,k,s,t,n,m,x,y,sum,w,d,cur[400],T,dist[400];
    bool a[8],vis[400];
    void addedge(int x,int y,int cap){
        edge[m++]=(Edge){y,x,cap,0};
        edge[m++]=(Edge){x,y,0,0};
        g[x].push_back(m-2);
        g[y].push_back(m-1);
    }
    bool bfs(){
        memset(vis,0,sizeof(vis));
        vis[s]=1;
        dist[s]=0;
        q.push(s);
        while(!q.empty()){
            int x=q.front();q.pop();
            for(int i=0;i<g[x].size();i++){
                Edge& e=edge[g[x][i]];
                if(e.cap>e.flow&&!vis[e.to]){
                    vis[e.to]=1;
                    dist[e.to]=dist[x]+1;
                    q.push(e.to);
                }
            }
        }
        return vis[t];
    }
    int dfs(int x,int a){
        if(x==t||!a)return a;
        int flow=0,f;
        for(int& i=cur[x];i<g[x].size();i++){
            Edge& e=edge[g[x][i]];
            if(dist[x]+1==dist[e.to]&&(f=dfs(e.to,min(a,e.cap-e.flow)))){
                e.flow+=f;
                edge[g[x][i]^1].flow-=f;
                flow+=f;
                a-=f;
                if(!a)break;
            }
        }
        return flow;
    }
    int maxflow(){
        int flow=0;
        while(bfs()){
            memset(cur,0,sizeof(cur));
            flow+=dfs(s,INF);
        }
        return flow;
    }
    int main()
    {
        scanf("%d",&T);
        while(T--){
            scanf("%d",&n);
            sum=m=0;t=351+n;
            for(i=1;i<=n;i++){
                for(j=1;j<=7;j++)scanf("%d",&a[j]);
                scanf("%d%d",&d,&w);
                sum+=d;
                addedge(s,i+350,d);
                for(j=1;j<=7;j++)
                if(a[j])for(k=0;k<w;k++)addedge(i+350,k*7+j,1);
            }
            for(i=1;i<=350;i++)addedge(i,t,1);
            if(maxflow()==sum)printf("Yes
    ");else printf("No
    ");
            for(i=0;i<=t;i++)g[i].clear();
        }
        return 0;
    }
    poj1698
  • 相关阅读:
    17、生鲜电商平台-异常模块的设计与架构
    16、生鲜电商平台-监控模块的设计与架构
    15、生鲜电商平台-售后模块的设计与架构
    14、生鲜电商平台-搜索模块的设计与架构
    13、生鲜电商平台-订单抽成模块的设计与架构
    12、生鲜电商平台-提现模块的设计与架构
    递归和回溯_leetcode77-经典的组合
    递归和回溯_leetcode52
    递归和回溯_leetcode51
    递归和回溯_leetcode46-经典的排列去重
  • 原文地址:https://www.cnblogs.com/gjghfd/p/5794964.html
Copyright © 2020-2023  润新知