• LibreOJ 6001 太空飞行计划(最大流)


    题解:首先源点向每个实验建边,流量为经费的值,实验向器材建边,值为无限大,器材向终点建边,值为价值

    然后跑一遍最大流就能跑出所谓的最大闭合图的点值之和.

    代码如下:

    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define hi puts("hi");
    #define inf 0x3f3f3f3f
    using namespace std;
    
    int v[100010],w[100010],head[100010],next[100010],deep[100010],first[100010],cur[100010];
    int n,m,s,t,cnt;
    
    void init()
    {
        cnt=-1;    //
        memset(head,-1,sizeof(head));
        memset(next,-1,sizeof(next));
    }
    
    void add(int from,int to,int cost)
    {
        cnt++;
        next[cnt]=head[from];   //
        v[cnt]=to;
        w[cnt]=cost;
        head[from]=cnt;
    }
    
    void add_edge(int from,int to,int cost)
    {
        add(from,to,cost);
        add(to,from,0);
    }
    
    int bfs(int s,int t)
    {
        queue<int> q;
        memset(deep,0,sizeof(deep));
        deep[s]=1;
        q.push(s);
        while(!q.empty())
        {
            int u=q.front();
            q.pop();
            for(int i=head[u]; i!=-1; i=next[i])
            {
                if(w[i]>0&&(!deep[v[i]]))
                {
                    deep[v[i]]=deep[u]+1;
                    q.push(v[i]);
                }
            }
        }
        if(!deep[t])
        {
            return 0;
        }
        return 1;
    }
    
    int dfs(int u,int t,int dist)
    {
        if(u==t)
        {
            return dist;
        }
        for(int i=head[u]; i!=-1; i=next[i])
        {
            if(w[i]&&(deep[v[i]]==deep[u]+1))  //!!!
            {
                int di=dfs(v[i],t,min(dist,w[i]));
                if(di>0)
                {
                    w[i]-=di;
                    w[i^1]+=di;
                    return di;
                }
            }
        }
        return 0;
    }
    
    int dinic(int s,int t)
    {
        int ans=0;
        while(bfs(s,t))
        {
            while(int d=dfs(s,t,inf))
            {
                ans+=d;
            }
        }
        return ans;
    }
    
    
    int main()
    {
        init();
        scanf("%d%d",&m,&n);
        int sum=0;
        s=0;
        t=n+m+1;
        int x;
        char c;
        for(int i=1; i<=m; i++)
        {
            scanf("%d",&x);
            sum+=x;
            add_edge(s,n+i,x);
            while(1)
            {
                scanf("%d%c",&x,&c);
                add_edge(n+i,x,inf);
                if(c=='
    '||c=='
    ')
                {
                    break;
                }
            }
        }
        for(int i=1; i<=n; i++)
        {
            scanf("%d",&x);
            add_edge(i,t,x);
        }
        sum-=dinic(s,t);
        for(int i=1;i<=m;i++)
        {
            if(deep[i+n])
            {
                printf("%d ",i);
            }
        }
        printf("
    ");
        for(int i=1;i<=n;i++)
        {
            if(deep[i])
            {
                printf("%d ",i);
            }
        }
        printf("
    ");
        printf("%d
    ",sum);
    }
  • 相关阅读:
    JS框架设计读书笔记之-选择器引擎02
    JS框架设计读书笔记之-选择器引擎01
    JS框架设计读书笔记之-小知识
    JS框架设计读书笔记之-函数
    JS框架设计读书笔记之-核心模块
    7.19 NOIP模拟6
    一 网络基础之网络协议篇
    Socket 网络编程
    Python 常用模块
    类的特殊成员
  • 原文地址:https://www.cnblogs.com/stxy-ferryman/p/8570090.html
Copyright © 2020-2023  润新知