zoukankan      html  css  js  c++  java
  • Bzoj 2502: 清理雪道 有上下界网络流_最小流

    好长时间没有写网络流了,感觉好手生.
    对于本题,设一个源点 $s$ 和 $t$.
    1.由 $s$ 向每个点连一条没有下界,容量为无限大的边,表示以该点为起点.
    2.由每个点向 $t$ 连一条没有下界,容量为无限大的边,表示以该点为终点.
    为了保证每条原图中得边都能被覆盖掉,再将原图中的边连一条无上界,下界为 1 的边.
    最后,跑一遍最小流即可.

    Code:

    // luogu-judger-enable-o2
    #include<bits/stdc++.h> 
    using namespace std;
    #define setIO(s) freopen(s".in","r",stdin) 
    #define maxn 2000
    #define inf 1000000  
    int tot; 
    void ini(){ tot=1000;  }
    int newnode(){ return ++tot; }
    struct Edge{
        int from,to,cap;
        Edge(int a=0,int b=0,int c=0):from(a),to(b),cap(c){} 
    }; 
    vector<int>G[maxn];
    vector<Edge>edges;  
    void addedge(int u,int v,int c){
        edges.push_back(Edge(u,v,c)); 
        edges.push_back(Edge(v,u,0));
        int m=edges.size(); 
        G[u].push_back(m-2);
        G[v].push_back(m-1); 
    } 
    namespace maxflow{
        int s,t; 
        int d[maxn],vis[maxn]; 
        int current[maxn]; 
        queue<int>Q; 
        int BFS(){
            memset(vis,0,sizeof(vis)); 
            vis[s]=1,d[s]=0; 
            Q.push(s); 
            while(!Q.empty()){
                int u=Q.front();Q.pop(); 
                int sz=G[u].size();
                for(int i=0;i<sz;++i){
                    Edge v=edges[G[u][i]];
                    if(!vis[v.to]&&v.cap>0) {
                        d[v.to]=d[u]+1,vis[v.to]=1;
                        Q.push(v.to); 
                    }
                }
            }
            return vis[t]; 
        }
        int dfs(int x,int cur){
            if(x!=t){
                int f,flow=0,sz=G[x].size();
                for(int i=current[x];i<sz;++i){
                    current[x]=i;  
                    Edge r = edges[G[x][i]]; 
                    if(d[r.to]==d[x]+1&&r.cap>0) {
                        f=dfs(r.to,min(cur,r.cap)); 
                        if(f>0){
                            flow+=f,cur-=f; 
                            edges[G[x][i]].cap-=f,edges[G[x][i]^1].cap+=f;               
                        }
                    }
                    if(!cur) break; 
                }
                return flow; 
            }
            else return cur; 
        }
        int GET(){
            int ans=0; 
            while(BFS()) {
                memset(current,0,sizeof(current)); 
                ans+=dfs(s,inf);   
            }
            return ans; 
        }
    }; 
    int main(){
        //setIO("input");    
        ini(); 
        int n,s,t,ss,tt; 
        s=0,t=newnode(),ss=newnode(),tt=newnode(); 
        scanf("%d",&n); 
        for(int i=1,m=0,v;i<=n;++i) {
            scanf("%d",&m); 
            while(m--){
                scanf("%d",&v); 
                addedge(i,v,inf-1),addedge(s,i,inf),addedge(v,t,inf); 
                addedge(ss,v,1),addedge(i,tt,1);   
            }
        }           
        int rec=edges.size(); 
        addedge(t,s,inf); 
        maxflow::s=ss,maxflow::t=tt; 
        maxflow::GET();     
        int ans1=edges[rec^1].cap; 
        edges[rec^1].cap=edges[rec].cap=0; 
        maxflow::s=t, maxflow::t=s; 
        ans1-=maxflow::GET(); 
        printf("%d",ans1); 
        return 0; 
    }
    

      

  • 相关阅读:
    QuickTest Professional对web网站进行测试后没有生成脚本信息解决办法
    如何使用loadrunner进行web网站性能测试
    spring boot架构浅谈
    spring cloud架构
    crontab误删操作的恢复与防范
    linux命令重定向>、>>、 1>、 2>、 1>>、 2>>、 <
    redis原理及使用
    PHP三种字符串界定符的区别(单引号,双引号,<<<)
    php代码加密|PHP源码加密——实现方法
    java一键搭建新项目(地址)
  • 原文地址:https://www.cnblogs.com/guangheli/p/10698140.html
Copyright © 2011-2022 走看看