zoukankan      html  css  js  c++  java
  • 10249

    Problem D

    The Grand Dinner

    Input: standard input

    Output: standard output

    Time Limit: 15 seconds

    Memory Limit: 32 MB

    Each team participating in this year’s ACM World Finals contest is expected to join the grand dinner to be arranged after the prize giving ceremony ends. In order to maximize the interaction among the members of different teams, it is expected that no two members of the same team sit at the same table.

    Now, given the number of members in each team (including contestants, coaches, reserves, guests etc.) and the seating capacity of each available table, you are to determine whether it is possible for the teams to sit as described in the previous paragraph. If such an arrangement is possible you must also output one possible seating arrangement. If there are multiple possible arrangements, any one is acceptable.

    Input

     The input file may contain multiple test cases. The first line of each test case contains two integers M (1 £ M £ 70) and N (1 £ N £ 50) denoting the number of teams and the number of tables respectively. The second line of the test case contains M integers where the i-th (1 £ i £ M) integer mi (1 £ mi £ 100) indicates the number of members of team i. The third line contains N integers where the j-th (1 £ j £ N) integer nj (2 £ nj £ 100) indicates the seating capacity of table j.

    A test case containing two zeros for M and N terminates the input.

    Output

    For each test case in the input print a line containing either 1 or 0 depending on whether or not there exists a valid seating arrangement of the team members. In case of a successful arrangement print M additional lines where the i-th (1 £ i £ M) of these lines contains a table number (an integer from 1 to N) for each of the members of team i.

     

    Sample Input

    4 5

    4 5 3 5

    3 5 2 6 4

    4 5

    4 5 3 5

    3 5 2 6 3

    0 0

     

     

    Sample Output

    1

    1 2 4 5

    1 2 3 4 5

    2 4 5

    1 2 3 4 5

    0


    (World Finals Warm-up Contest, Problem Setter: Rezaul Alam Chowdhury)

    建模:

    1.每个队伍为一个点,每张饭桌为一个点,添加源点、汇点;

    2.源点指向队伍弧容量为该队伍人数;添加每个队伍指向每张饭桌容量为1的弧,表示最多去一个队员;添加每张饭桌到汇点的容量为桌子的size的弧。

    最后找有流量的弧即可。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<vector>
    #include<cstdlib>
    #include<algorithm>
    #include<queue>
    
    using namespace std;
    
    #define LL long long
    #define ULL unsigned long long
    #define UINT unsigned int
    #define MAX_INT 0x7fffffff
    #define MAX_LL 0x7fffffffffffffff
    #define MAX(X,Y) ((X) > (Y) ? (X) : (Y))
    #define MIN(X,Y) ((X) < (Y) ? (X) : (Y))
    #define INF 10000000
    #define MAXN 125
    #define MAXM 8000
    
    struct edge{
        int u, v, cap, flow, nxt;
    }e[MAXM];
    int h[MAXN], cc;
    
    void add(int u, int v, int cap){
        e[cc]=(edge){u, v, cap, 0, h[u]};
        h[u]=cc++;
        e[cc]=(edge){v, u, 0, 0, h[v]};
        h[v]=cc++;
    }
    
    int s, t, cur[MAXN];
    
    int vis[MAXN], d[MAXN];
    bool bfs(){
        queue<int> q;       q.push(s);
        memset(vis, 0, sizeof(vis));
        d[s]=0;     vis[s]=1;
        while(!q.empty()){
            int u=q.front();    q.pop();
            for(int i=h[u]; i!=-1; i=e[i].nxt){
                int v=e[i].v, cap=e[i].cap, ef=e[i].flow;
                if(!vis[v] && cap>ef){
                    vis[v]=1;
                    d[v]=d[u]+1;
                    q.push(v);
                }
            }
        }
        return vis[t]==1;
    }
    
    int dfs(int u, int a){
        if(u==t || a==0) return a;
        int f, flow=0;
        for(int &i=cur[u]; i!=-1; i=e[i].nxt){
            int v=e[i].v, cap=e[i].cap, ef=e[i].flow;
            if(d[v]==d[u]+1 && (f=dfs(v, MIN(a, cap-ef)))>0){
                e[i].flow+=f;
                e[i^1].flow-=f;
                flow+=f;
                a-=f;
                if(!a) break;
            }
        }
        return flow;
    }
    
    bool Dinic(const int sum, int n){
        int flow=0, i;
        while(bfs()){
            for(i=0; i<n; i++) cur[i]=h[i];
            flow+=dfs(s, INF);
        }
        return flow==sum;
    }
    
    void print(int tc, int m){
        printf("1
    ");
        vector<int> ans[77];
        for(int i=tc; i<cc; i+=2) if(e[i].flow){
            int u=e[i].u, v=e[i].v;
            ans[u].push_back(v-m);
        }
        for(int i=1; i<=m; i++){
            if(!ans[i].size()) continue;
            printf("%d", ans[i][0]);
            for(int j=1; j<ans[i].size(); j++)
                printf(" %d", ans[i][j]);
            printf("
    ");
        }
    }
    
    int main(){
    //    freopen("C:\Users\Administrator\Desktop\in.txt","r",stdin);
        int n, m;
        while(scanf(" %d %d", &m, &n)==2 && (m || n)){
            int i, j, sum=0;
            memset(h, -1, sizeof(h));   cc=0;
            for(i=0; i<m; i++){
                int tmp;
                scanf(" %d", &tmp);
                if(tmp) add(0, i+1, tmp);
                sum+=tmp;
            }
            for(i=0; i<n; i++){
                int tmp;
                scanf(" %d", &tmp);
                if(tmp) add(i+1+m, n+m+1, tmp);
            }
            int tc=cc;
            for(i=0; i<m; i++)
                for(j=0; j<n; j++)
                    add(i+1, j+1+m, 1);
            s=0;    t=n+m+1;
            if(Dinic(sum, n+m+2)) print(tc, m);
            else printf("0
    ");
        }
        return 0;
    }
    
  • 相关阅读:
    禁止select下拉框的其中某个选择项不能被选择
    jQuery 增加 删除 修改select option
    jquery ajax后台向前台传list 前台用jquery $.each遍历list
    转载 java枚举类型enum的使用 (原文地址:http://blog.csdn.net/wgw335363240/article/details/6359614)
    C#性能优化实践 资料整理
    MySql 优化 网上资料
    第06组 Alpha冲刺(4/6)
    第06组 Alpha冲刺(3/6)
    第06组 Alpha冲刺(2/6)
    第06组 Alpha冲刺(1/6)
  • 原文地址:https://www.cnblogs.com/ramanujan/p/3348219.html
Copyright © 2011-2022 走看看