• 最大权闭合图


    最大权闭合图完美的解决了网络流中,对节点间>1的依赖关系。

    hdu 5845 (二分+最大权闭合图)

    #include <math.h>
    #include <time.h>
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <set>
    #include <map>
    #include <string>
    #include <stack>
    #include <queue>
    #include <vector>
    #include <bitset>
    #include <iostream>
    #include <algorithm>
    #define pb push_back
    #define fi first
    #define se second
    #define icc(x) (1<<(x))
    #define lcc(x) (1ll<<(x))
    #define lowbit(x) (x&-x)
    #define debug(x) cout<<#x<<"="<<x<<endl
    #define rep(i,s,t) for(int i=s;i<t;++i)
    #define per(i,s,t) for(int i=t-1;i>=s;--i)
    #define mset(g, x) memset(g, x, sizeof(g))
    using namespace std;
    
    typedef long long ll;
    typedef unsigned long long ull;
    typedef unsigned int ui;
    typedef double db;
    typedef pair<int,int> pii;
    typedef pair<ll,ll> pll;
    typedef vector<int> veci;
    const int mod=(int)1e9+7,inf=0x3fffffff,rx[]={-1,0,1,0},ry[]={0,1,0,-1};
    const ll INF=1ll<<60;
    const db pi=acos(-1),eps=1e-8;
    
    template<class T> void rd(T &res){
        res = 0; int ch,sign=0;
        while( (ch=getchar())!='-' && !(ch>='0'&&ch<='9'));
        if(ch == '-') sign = 1; else res = ch-'0';
        while((ch=getchar())>='0'&&ch<='9') res = (res<<3)+(res<<1)+ch-'0';
        res = sign?-res:res;
    }
    template<class T>void rec_pt(T x){
        if(!x)return;
        rec_pt(x/10);
        putchar(x%10^48);
    }
    template<class T>void pt(T x){
        if(x<0) putchar('-'),x=-x;
        if(!x)putchar('0');
        else rec_pt(x);
    }
    template<class T>inline void ptn(T x){ pt(x),putchar('
    '); }
    template<class T>inline void Max(T &a,T b){ if(b>a)a=b; }
    template<class T>inline void Min(T &a,T b){ if(b<a)a=b; }
    template<class T>inline T mgcd(T b,T d){ return b?mgcd(d%b,b):d; }//gcd模板,传入的参数必须是用一类型
    //-------------------------------主代码--------------------------------------//
    
    //网络流SAP模板,复杂度O(N^2*M)
    //使用前调用init(源点,汇点,图中点的个数),然后调用add_edge()加边
    //调用getflow得出最大流
    #define N 404
    #define M 2*N*N
    
    
    
    struct Max_Flow
    {
        struct node
        {
            int to,w,next;
        }edge[M];
        
        int s,t;
        int nn;
        int cnt,pre[N];
        int lv[N],gap[N];
        
        void init(int ss,int tt,int num)
        {
            s=ss;
            t=tt;
            nn = num;//
            cnt=0;
            memset(pre,-1,sizeof(pre));
        }
        void add_edge(int u,int v,int w)//同时建两条边
        {
            edge[cnt].to=v;
            edge[cnt].w=w;
            edge[cnt].next=pre[u];
            pre[u]=cnt++;
            
            edge[cnt].to=u;
            edge[cnt].w=0;
            edge[cnt].next=pre[v];
            pre[v]=cnt++;
        }
        
        int sdfs(int k,int w)
        {
            if(k==t) return w;
            int f=0;
            int mi=nn-1;
            for(int p=pre[k];p!=-1;p=edge[p].next)
            {
                int v=edge[p].to,tw=edge[p].w;
                if(tw!=0)
                {
                    if(lv[k]==lv[v]+1)
                    {
                        int tmp=sdfs(v,min(tw,w-f));
                        f+=tmp;
                        edge[p].w-=tmp;
                        edge[p^1].w+=tmp;
                        if(f==w||lv[s]==nn) break;
                    }
                    if(lv[v]<mi) mi=lv[v];
                }
            }
            if(f==0)
            {
                gap[lv[k]]--;
                if( gap[ lv[k] ]==0 )
                {
                    lv[s]=nn;
                }
                lv[k]=mi+1;
                gap[lv[k]]++;
            }
            return f;
        }
        
        int getflow()
        {
            int sum=0;
            memset(lv,0,sizeof(lv));
            memset(gap,0,sizeof(gap));
            gap[0]=nn;
            while(lv[s]<nn)
            {
                sum+=sdfs(s,inf);
            }
            return sum;
        }
        
    }ff;
    
    int pay[202],pro[202],costtime[202];
    int mat[202][202];
    int mark[202];
    
    int main()
    {
        int T;
        rd(T);
        int tt = 1;
        while (T--) {
            int n,m,L;
            rd(n),rd(m),rd(L);
            int b = 0,d = 1e9+1;
            rep(i, 1, n+1){
                rd(pay[i]); rd(costtime[i]);
            }
            mset(mat, 0);
            rep(i, 1, m+1){
                rd(pro[i]);
                int k;
                rd(k);
                rep(j, 0, k){
                    int tmp;
                    rd(tmp);
                    mat[i][tmp] = 1;
                }
            }
            int sum = 0;
            int ans = 0;
            while(b < d){
                int mid = (b+d)/2;
                mset(mark, 0);
                ff.init(0, n+m+1, n+m+2);
                rep(i, 1, n+1){
                    if(costtime[i]<=mid){
                        ff.add_edge(m+i, n+m+1, pay[i]);
                        mark[i] = 1;
                    }
                }
                sum = 0;
                rep(i, 1, m+1){
                    int flag = 0;
                    rep(j, 1, n+1){
                        if(mat[i][j]==1 && mark[j]==0){
                            flag = 1;
                            break;
                        }
                    }
                    if(flag == 0)
                    {
                        sum += pro[i];
                        ff.add_edge(0, i, pro[i]);
                        rep(j, 1, n+1){
                            if(mat[i][j] == 1){
                                ff.add_edge(i, m+j, inf);
                            }
                        }
                    }
                }
                int flow = ff.getflow();
                sum -= flow;
                if(sum>=L) d = mid,ans = sum;
                else b = mid+1;
            }
            
            printf("Case #%d: ",tt++);
            if(b >= 1e9+1){
                printf("impossible
    ");
            }else
            {
                pt(b); putchar(' '); ptn(ans);
            }
            
        }
        return 0;
    }
  • 相关阅读:
    java 11 值得关注的新特性
    MessageDigest来实现数据加密
    LinkedList(JDK1.8)源码分析
    gradle配置统一管理
    Android 新架构组件 -- WorkManager
    RF使用ie浏览器访问页面,浏览器启动只显示This is the initial start page for the WebDriver server,页面访问失败
    jenkins配置RF构建结果显示
    jenkins配置QQ邮箱自动发送RF测试构建结果通知邮件
    RF变量列表类型@{}和${}列表类型的关系
    jekins构建通知邮件配置及邮件附件设置,jenkins构建通知邮件没有RF的log和report文件
  • 原文地址:https://www.cnblogs.com/chenhuan001/p/5809386.html
Copyright © 2020-2023  润新知