zoukankan      html  css  js  c++  java
  • [网络流24题] 太空飞行计划问题

    这道题目的核心是模型转化

    将题意反过来考虑,变成“要求选出一个实验的集合,那么这个集合所附带的器材必须选,求最大点权和”

    转化为最大权闭合子图

    做法:

    从源点向每一个实验连边,容量为实验的收益

    每个实验和它依赖的仪器之间连inf边

    从仪器向汇点连边,容量为仪器费用

    跑S-T最大流,用实验的总收益减去最大流的值就是最大收益

    具体方案的输出,在最后一次分层图bfs(就是没到达汇点的那次)中访问过的点就是选要择的

    Code:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define inf 1e9
    using namespace std;
    char tmpch;
    inline int read(){
        int re=0,flag=1;char ch=tmpch;
        //if(ch=='
    '||ch=='
    ') exit(0);
        while(ch>'9'||ch<'0'){
            /*cout<<"useless char "<<(int)ch<<"
    ";*/
            /*if((int)ch==-1) exit(0); */
            if(ch=='-') flag=-1; 
            ch=getchar();
        }
        while(ch>='0'&&ch<='9') re=(re<<1)+(re<<3)+ch-'0',ch=getchar();
        tmpch=ch;
        //cout<<"read in "<<re*flag<<"
    ";
        return re*flag;
    }
    int n,m,cnt=-1,ans=0,first[110],cur[110],dep[110];
    struct edge{
        int to,next,w;
    }a[10010];
    inline void add(int u,int v,int w){
        //cout<<"add "<<u<<" "<<v<<" "<<w<<"
    ";
        a[++cnt]=(edge){v,first[u],w};first[u]=cnt;
        a[++cnt]=(edge){u,first[v],0};first[v]=cnt;
    }
    bool bfs(int s,int t){
        int i,u,v,q[110],head=0,tail=1;
        for(i=s;i<=t;i++) dep[i]=-1,cur[i]=first[i];
        dep[s]=0;q[0]=s;
        while(head<tail){
            u=q[head++];
            //cout<<"bfs "<<u<<" "<<dep[u]<<"
    ";
            for(i=first[u];~i;i=a[i].next){
                v=a[i].to;
                if(~dep[v]||!a[i].w) continue;
                dep[v]=dep[u]+1;q[tail++]=v;
            }
        }
        return ~dep[t];
    }
    int _min(int l,int r){return (l<r)?l:r;}
    int dfs(int u,int t,int limit){
        if(u==t||!limit) return limit;
        int i,v,f,flow=0;
        for(i=first[u];~i;i=a[i].next){
            v=a[i].to;
            if((dep[v]==dep[u]+1)&&(f=dfs(v,t,_min(limit,a[i].w)))){
                flow+=f;limit-=f;
                a[i].w-=f;a[i^1].w+=f;
                if(!limit) return flow;
            }
        }
        return flow;
    }
    void dinic(int s,int t){
        while(bfs(s,t)) ans+=dfs(s,t,inf);
    }
    int main(){
        freopen("shuttle.in","r",stdin);
        freopen("shuttle.out","w",stdout);
        memset(first,-1,sizeof(first));
        int i,t1,sum=0;
        n=read();m=read();tmpch=0;
        for(i=1;i<=n;i++){
            t1=read();add(0,i,t1);sum+=t1;
            tmpch=0;
            //cout<<"experiment "<<i<<"
    ";
            while(((t1=read())||1)&&tmpch!='
    '&&tmpch!='
    ') add(i,n+t1,inf);
            tmpch=0;add(i,n+t1,inf);
        }
        //cout<<"finish experiment
    ";
        for(i=1;i<=m;i++) t1=read(),add(n+i,m+n+1,t1);
        //cout<<"finish read in
    ";tmpch=0;
        dinic(0,n+m+1);
        for(i=1;i<=n;i++) if(~dep[i]) printf("%d ",i);printf("
    ");
        for(i=1;i<=m;i++) if(~dep[n+i]) printf("%d ",i);printf("
    ");
        printf("%d
    ",sum-ans);
        return 0;
    }
  • 相关阅读:
    四、MYSQL的数据类型
    一、InnoDB引擎
    Spring源码分析(一)
    ActiveMQ 的安装与使用(springboot版本)
    12、JAVA内存模型与线程
    9、虚拟机字节码执行引擎
    8、类加载机制
    7、Class文件的格式
    6、使用jconsole+VisualVM分析JVM
    5、JVM的监控与分析工具
  • 原文地址:https://www.cnblogs.com/dedicatus545/p/8398392.html
Copyright © 2011-2022 走看看