• 1737: 太空飞行计划问题 最大权闭合子图


    1、建立两个超级点S,T。

    2、对每个实验跟S链接一条容量为收入的边。

    3、对每个一起跟T链接一条容量为花费的边。

    4、对每个实验要用到的一起链接一条容量为无穷大的边。

    链表

    #include <iostream>
    #include <queue>
    #include <vector>
    #include <cstdio>
    #include <cstring>
    using namespace std;
     
    const int MAXN = 101,MAXM = MAXN*MAXN*2,INF = ~0U >> 1;
    struct Edge{
       Edge *next,*op;
       int t,c;
    }*V[MAXN],*P[MAXN],ES[MAXM],*Stae[MAXN];
    int N,M,S,T,EC,Ans,Maxflow;
    int Lv[MAXN],Stap[MAXN];
    void Clear()
    {
        for(int i = 0;i < MAXN;++i)
            V[i] = NULL,ES[i].next = NULL,ES[i].op = NULL;
        EC = 0; Ans = 0; Maxflow = 0;
    }
    inline void addedge(int a,int b,int c)
    {
        ES[++EC].next = V[a];V[a] = ES+EC;V[a]->t = b;V[a]->c = c;
        ES[++EC].next = V[b];V[b] = ES+EC;V[b]->t = a;V[b]->c = 0;
        V[a]->op = V[b]; V[b]->op = V[a];
    }
    bool Dinic_Lable()               //构造层次图
    {
        int head,tail,i,j;
        Stap[head=tail=0] = S;
        memset(Lv,-1,sizeof(Lv));
        Lv[S] = 0;
        while(head<=tail){
            i = Stap[head++];
            for(Edge *e = V[i];e;e = e->next){
                j = e->t;
                if(e->c&&Lv[j]==-1){
                    Lv[j] = Lv[i] + 1;
                    if(j==T)
                        return true;
                    Stap[++tail] = j;
                }
            }
        }
        return false;
    }
    void Dinic_Augment()            //增广
    {
        int i,j,delta,Stop;
        for(i = S;i <= T;++i)
            P[i] = V[i];
        Stap[Stop=1] = S;
        while(Stop){
            i = Stap[Stop];
            if(i != T){
                for(;P[i];P[i] = P[i]->next)
                    if(P[i]->c&&Lv[i]+1==Lv[j=P[i]->t])
                       break;
                if(P[i]){
                    Stap[++Stop] = j;
                    Stae[Stop] = P[i];
                }
                else
                    Stop--,Lv[i] = -1;
            }
            else
            {
                delta = INF;
                for(i = Stop;i >= 2;--i)
                    if(Stae[i]->c < delta)
                        delta = Stae[i]->c;
                Maxflow += delta;
                for(i = Stop;i >= 2;--i){
                    Stae[i]->c -= delta;
                    Stae[i]->op->c += delta;
                    if(Stae[i]->c == 0)
                        Stop = i-1;
                }
            }
     
        }
    }
    void Dinic()
    {
        while(Dinic_Lable())
            Dinic_Augment();
    }
    void init()
    {
        int i,a,c;
        S = 0; T = M+N+1;
        for(i = 1;i <= M;++i){
            scanf("%d",&c);
            addedge(S,i,c);
            Ans += c;
    //        for(;;){
    //            int sum = 0;
    //            c = getchar();
    //            while(c == ' ')c = getchar();
    //            if(c=='
    ') break;
    //            while(c!=' '&&c!='
    '){
    //                sum *= 10;
    //                sum += c - '0';
    //                c = getchar();
    //            }              printf("sum ==  %d
    ",sum);
    //            addedge(i,sum+M,INF);
    //            if(c=='
    ') break;
    //        }
            for (;;){
                while((c=getchar())==' '); ungetc(c,stdin);
                if (c==10 || c==13) break;
                scanf("%d",&a);
                addedge(i,a+M,INF);
            }
        }
     
        for(i = 1;i <= N;++i){
            scanf("%d",&c);
            addedge(i+M,T,c);
        }
    }
    void print()
    {
        for(int i = 1;i <= M;++i)
            if(Lv[i]!=-1)
               printf("%d ",i);
        putchar('
    ');
        for(int i = M+1;i <= M+N;++i)
            if(Lv[i]!=-1)
               printf("%d ",i-M);
        Ans -= Maxflow;
        printf("
    %d
    ",Ans);
    }
    int main()
    {
    //    freopen("Input.txt","r",stdin);
        while(~scanf("%d%d",&M,&N)){
            Clear();
            init();
            Dinic();
            print();
        }
        return 0;
    }
     
      

    容器实现

    #include <iostream>
    #include <algorithm>
    #include <sstream>
    #include <vector>
    #include <queue>
    #include <cstdio>
    #include <cstring>
    using namespace std;
     
    const int MAXN = 1e3 + 5,INF = ~0U >> 2;
    struct Edge{
       int from,to,cap,flow;
       Edge(int f,int t,int c,int _f)
           :from(f),to(t),cap(c),flow(_f){};
    };
    vector<Edge> edges;
    vector<int> G[MAXN];
    int N,M,S,T;
    int d[MAXN],cur[MAXN];
    bool vst[MAXN];
    void Init()
    {
        for(int i = 0;i < MAXN;++i)
            G[i].clear();
        edges.clear();
    }
    inline void AddEdge(int from,int to,int cap)
    {
        edges.push_back(Edge(from,to,cap,0));
        edges.push_back(Edge(to,from,0,0));
        int sz = edges.size();
        G[from].push_back(sz-2);
        G[to].push_back(sz-1);
    }
    bool BFS()
    {
        memset(vst,false,sizeof(vst));
        queue<int> Q;
        Q.push(S);
        d[S] = 0;
        vst[S] = true;
        while(!Q.empty()){
            int x = Q.front();
            Q.pop();
            for(int i = 0;i < (int)G[x].size();++i){
                Edge& e = edges[G[x][i]];
                if(!vst[e.to]&&e.cap>e.flow){
                    vst[e.to] = true;
                    d[e.to] = d[x] + 1;
                    Q.push(e.to);
                }
            }
        }
        return vst[T];
    }
    int DFS(int u,int a)
    {
        if(u==T||a==0)
            return a;
        int f,flow = 0;
        for(int& i = cur[u];i < (int)G[u].size();++i){
             Edge& e = edges[G[u][i]];
             if(d[u]+1==d[e.to]&&(f=DFS(e.to,min(a,e.cap-e.flow)))>0){
                 e.flow += f;
                 edges[G[u][i]^1].flow -= f;
                 flow += f;
                 a -= f;
                 if(a==0)break;
             }
        }
        return flow;
    }
    int Maxflow()
    {
        int flow = 0;
        while(BFS()){
            memset(cur,0,sizeof(cur));
            flow += DFS(S,INF);
        }
        return flow;
    }
    void Solve()
    {
        int i,c,ans = 0;
        S = 0; T = M+N+1;
        for(i = 1;i <= M;++i){
            scanf("%d",&c);
            AddEdge(S,i,c);
            ans += c;
            string str;
            getline(cin,str);
            istringstream ssin(str);
            while(ssin>>c)
                AddEdge(i,c+M,INF);
        }
        for(i = 1;i <= N;++i){
            scanf("%d",&c);
            AddEdge(i+M,T,c);
        }
        int maxflow = Maxflow();
        for(i = 1;i <= M;++i)
           if(vst[i])
             printf("%d ",i);
        putchar('
    ');
        for(i = M+1;i <= M+N;++i)
           if(vst[i])
              printf("%d ",i-M);
        printf("
    %d
    ",ans-maxflow);
    }
    int main()
    {
    //    freopen("Input.txt","r",stdin);
        while(~scanf("%d%d",&M,&N)){
            Init();
            Solve();
        }
        return 0;
    }
     
      
  • 相关阅读:
    set, bag, list, map的语义
    ExtJs 自定义Vtype验证
    详解.NET中的动态编译技术
    IL汇编语言介绍(译)
    C# 文件操作相关
    邮件系统
    关于Nhibernate中的多数据库支持
    .NET中 用C#操纵IIS
    ExtJS日期格式
    完全详解使用Resource实现多语言的支持
  • 原文地址:https://www.cnblogs.com/Aragaki/p/7528578.html
Copyright © 2020-2023  润新知