zoukankan      html  css  js  c++  java
  • 1090: MTM (费用流)

    1090: MTM

    Time Limit:3000/1000 MS (Java/Others)   Memory Limit:163840/131072 KB (Java/Others)
    Total Submissions:127   Accepted:19
    [Submit][Status][Discuss]

    Description

    MTM is not only a good ACMer but also a good teacher. There are n" role="presentation">n

    students in MTM’s class. Every student has two skills, each measured as a number:ai" role="presentation">ai – the programming skill andbi" role="presentation">bi

    – the math skill.

    Both ACM competition and Math competition will be held soon. So MTM decides to compose two teams to take part in these competitions. Because of the limitation of the number of student, MTM has to select p" role="presentation">p

    students to take part in the ACM competition ands" role="presentation">s

    students to take part in the Math competition. A student can't be a member of both teams.

    MTM considers that his expected result is equal to the sum of two values: the ACM team strength and the Math team strength. The strength of each team is the sum of skills of its members in the corresponding area.

    Help MTM to compose two teams to maximize his expected result.

    Input

    The input test file will contain multiple test cases. The first line of each input contains three positive integer numbers n" role="presentation">n

    , p" role="presentation">p and s" role="presentation">s (2 ≤ n ≤ 500" role="presentation">2≤n≤500, p + s ≤ n" role="presentation">p+s≤n) --- the number of students, the size of the ACM team and the size of the Math team.

    The second line contains n" role="presentation">n positive integers a1, a2, …, an" role="presentation">a1,a2,…,an (1 ≤ ai ≤ 500" role="presentation">1≤ai≤500), where ai" role="presentation">ai is the programming skill of the i" role="presentation">i-th student.

    The third line containsn" role="presentation">n positive integersb1, b2, …, bn" role="presentation">b1,b2,…,bn (1 ≤ bi ≤ 500" role="presentation">1≤bi≤500), wherebi" role="presentation">bi is the math skill of thei" role="presentation">i

    -th student.

    Output

    In the first line, print the maximum strength of MTM’s expected result. In the second line, print p numbers — the members of the ACM team. In the third line, print s numbers — the members of the Math team.

    The students are numbered from 1" role="presentation">1

    ton" role="presentation">n

    as they are given in the input. All numbers printed in the second and in the third lines should be distinct and should be printed in ascending order.

    Sample Input

    5 2 2
    1 3 4 5 2
    5 3 2 1 4
    
    4 2 2
    10 8 8 3
    10 7 9 4
    
    5 3 1
    5 2 5 1 7
    6 3 1 6 3
    

    Sample Output

    18
    3 4
    1 5
    31
    1 2
    3 4
    23
    1 3 5
    4
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <time.h>
    #include <string>
    #include <map>
    #include <stack>
    #include <vector>
    #include <set>
    #include <queue>
    #define inf 0x7fffffff
    #define mod 10000
    #define met(a,b) memset(a,b,sizeof a)
    typedef long long ll;
    using namespace std;
    const int N = 3000+10;
    const int M = 1000000;
    set<int>ac,ma;
    int n,p,s;
    int acm[N],math[N];
    struct Edge {
      int from, to, cap, flow;
      int  cost;
    };
    inline int Min(int aa,int bb)
    {
        return aa<bb?aa:bb;
    }
    struct MCMF {
      int n, m, s, t;
      vector<Edge> edges;
      vector<int> G[N];
      int inq[N];         // 是否在队列中
      int d[N];           // Bellman-Ford
      int p[N];           // 上一条弧
      int a[N];           // 可改进量
      void init(int n) {
        this->n = n;
        for(int i = 0; i < n; i++) G[i].clear();
        edges.clear();
      }
    
      void addedge(int from, int to, int cap, int cost) {
        edges.push_back((Edge){from, to, cap, 0, cost});
        edges.push_back((Edge){to, from, 0, 0, -cost});
        m = edges.size();
        G[from].push_back(m-2);
        G[to].push_back(m-1);
      }
    
      bool BellmanFord(int s, int t, int& flow,int& cost) {
        for(int i = 0; i < n; i++) d[i] = inf;
        memset(inq, 0, sizeof(inq));
        d[s] = 0; inq[s] = 1; p[s] = 0; a[s] = inf;
    
        queue<int> Q;
        Q.push(s);
        while(!Q.empty()) {
          int u = Q.front(); Q.pop();
          inq[u] = 0;
          int l=G[u].size();
          for(int i = 0; i < l; i++) {
            Edge& e = edges[G[u][i]];
            if(e.cap > e.flow && d[e.to] > d[u] + e.cost) {
              d[e.to] = d[u] + e.cost;
              p[e.to] = G[u][i];
              a[e.to] = Min(a[u], e.cap - e.flow);
              if(!inq[e.to]) { Q.push(e.to); inq[e.to] = 1; }
            }
          }
        }
        if(d[t] == inf) return false;
        cost += d[t]*a[t];
        int u = t;
        while(u != s) {
          edges[p[u]].flow += a[t];
          edges[p[u]^1].flow -= a[t];
          u = edges[p[u]].from;
        }
        return true;
      }
      // 需要保证初始网络中没有负权圈
        void Mincost(int s, int t) {
            int cost = 0;
            int flow=0;
            while(BellmanFord(s, t,flow, cost));
            printf("%d
    ",-cost);
        }
    }g;
    int main() {
        int k;
        while(~scanf("%d%d%d",&n,&p,&s) ) {
            g.init(n+4);
            ac.clear();ma.clear();
            for(int i=1;i<=n;i++)scanf("%d",&acm[i]);
            for(int i=1;i<=n;i++)scanf("%d",&math[i]);
            for(int i=1;i<=n;i++){
                g.addedge(0,i,1,0);
                g.addedge(i,n+1,1,-acm[i]);
                g.addedge(i,n+2,1,-math[i]);
            }
            g.addedge(n+1,n+3,p,0);g.addedge(n+2,n+3,s,0);
            int ans=0;
            g.Mincost(0,n+3);
    
            for(int i=0;i<g.m;i++){
                Edge temp=g.edges[i];
                if(temp.to==n+1&&temp.flow==1) {
                    ac.insert(temp.from);
                }
                else if(temp.to==n+2&&temp.flow==1) {
                    ma.insert(temp.from);
                }
            }
            bool f=false;
            for(int x:ac){
                    if (f==false){
                        printf("%d",x);
                        f=true;
                    }
                    else
                        printf(" %d",x);
            }
            printf("
    ");
            f=false;
            for(int x:ma){
                    if (f==false){
                        printf("%d",x);
                        f=true;
                    }
                    else
                        printf(" %d",x);
            }
            printf("
    ");
        }
        return 0;
    }
  • 相关阅读:
    你试过不用if撸代码吗?
    Chrome开发者工具Debug入门
    我为什么推荐Prettier来统一代码风格
    使用JSDoc自动生成代码文档
    Async/Await是这样简化JavaScript代码的
    C#泛型约束 (转载)
    DateTime , DateTime2 ,DateTimeOffset 之间的小区别 (转载)
    允许跨域资源共享(CORS)携带 Cookie (转载)
    C#中如何利用操作符重载和转换操作符 (转载)
    EF Core 2.1 Raw SQL Queries (转自MSDN)
  • 原文地址:https://www.cnblogs.com/jianrenfang/p/6548276.html
Copyright © 2011-2022 走看看