记录编号 417904 评测结果 AAAAAAAAAA
题目名称 [网络流24题] 太空飞行计划 最终得分 100
用户昵称 GravatarHeHe 是否通过 通过
代码语言 C++ 运行时间 0.002 s
提交时间 2017-06-28 16:20:22 内存使用 0.82 MiB
显示代码纯文本
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;

namespace IO{
    inline char getc(void);
    inline int in(void);
    inline void write(void);
    inline void write(int x);
    inline void write_all(void);
    
    char ops[1 << 18], *opt = ops, *const opt_end = ops + (1 << 18);
    char *num = new char[20];

    inline char getc(void){
        static char buf[1 << 18], *fs, *ft;
        return (fs == ft && (ft = (fs = buf) + fread(buf, 1, 1 << 18, stdin)), fs == ft) ? EOF : *fs++;
    }

    inline int in(void){
        register int res = 0;
        register char tmp = getc();
        while(!isdigit(tmp)) tmp = getc();
        while(isdigit(tmp))
            res = (res + (res << 2) << 1) + (tmp ^ 48),
            tmp = getc();
        return res;
    }

    inline int get_line(int *s){ 
        register char tmp = getc();
        register int res = 0;
        register int cnt = 0;

        while(!isdigit(tmp)) tmp = getc();
        while(isdigit(tmp))
            res = (res + (res << 2) << 1) + (tmp ^ 48),
            tmp = getc();
        *(s++) = res;
        ++cnt;

        while(tmp ^ '\n' && tmp ^ '\r'){ 
            while(!isdigit(tmp) && tmp ^ '\n' && tmp ^ '\r') tmp = getc();
            if(tmp == '\n' || tmp == '\r') return cnt;
            res = 0;
            while(isdigit(tmp))
                res = (res + (res << 2) << 1) + (tmp ^ 48),
                tmp = getc();
            *(s++) = res;
            ++cnt;
        }
        return cnt;
    }

    inline void write(int x){
        if(x < 0){ 
            x = -x;
            *(opt++) = '-';
            if(opt == opt_end) write_all();
        }

        do{
            *(++num) = (x % 10) | 0x30;
            x /= 10;
        }while(x);

        while(*num){
            *(opt++) = *(num--);
            if(opt == opt_end) write_all();
        }

        *(opt++) = ' ';
        if(opt == opt_end) write_all();
        return ;
    }

    inline void write(void){
        *(opt++) = '\n';
        if(opt == opt_end) write_all();
        return ;
    }

    inline void write_all(void){
        fwrite(ops, 1, opt - ops, stdout);
        opt = ops;
        return ;
    }
}
using IO::in;
using IO::get_line;
using IO::write;
using IO::write_all;

const int MAXN = 1e3 + 10;
const int INF = 0x7fffffff;

struct EDGE{
    int to, cap;
    EDGE *ne, *rcap;

    EDGE(){;}
    EDGE(int _to, EDGE *_ne, int _cap){
        to = _to, ne = _ne, cap = _cap;
    }
};

inline void add_edge(int fr, int to, int cap);
inline bool bfs(void);
int dfs(int u, int Min);

EDGE *head[MAXN];
int bfn[MAXN];
int S, T, max_flow;
int N, M, tot;
int *const tmp = new int[110];

int main(){ 
#ifndef LOCAL
    freopen("shuttle.in", "r", stdin);
    freopen("shuttle.out", "w", stdout);
#endif
    N = in(), M = in();
    S = 0, T = N + M + 1;
    for(int i = 1, cnt; i <= N; ++i){ 
        cnt = get_line(tmp);
        tot += *tmp;
        add_edge(S, i, tmp[0]);
        for(int j = 1; j < cnt; ++j){ 
            add_edge(i, tmp[j] + N, INF);
        }
    }
    delete []tmp;

    for(int i = N + 1; i < T; ++i){ 
        add_edge(i, T, in());
    }
    int tmp;
    while(bfs()){ 
        while((tmp = dfs(S, INF))) max_flow += tmp;
    }

    for(int i = 1; i <= N; ++i) if(bfn[i] > 0) write(i);
    write();
    for(int i = N + 1; i < T; ++i) if(bfn[i] > 0) write(i - N);
    write();
    write(tot - max_flow);

    write_all();
    return 0;
}

inline void add_edge(int fr, int to, int cap){
    head[fr] = new EDGE(to, head[fr], cap);
    head[to] = new EDGE(fr, head[to], 0);
    head[fr]->rcap = head[to];
    head[to]->rcap = head[fr];
    return ;
}

inline bool bfs(void){
    static queue<int> que;
    static int u, v;

    memset(bfn, 0x00, sizeof(bfn));
    while(!que.empty()) que.pop();

    bfn[S] = 1;
    que.push(S);

    while(!que.empty()){
        u = que.front();
        que.pop();
        if(u == T) return true;

        for(register EDGE *e = head[u]; e; e = e->ne){ 
            if(!e->cap || bfn[v = e->to]) continue;
            bfn[v] = bfn[u] + 1;
            que.push(v);
        }
    }

    return false;
}

int dfs(int u, int Min){ 
    if(u == T) return Min;
    register int sum;
    for(register EDGE *e = head[u]; e; e = e->ne){ 
        if(e->cap && bfn[e->to] == bfn[u] + 1 && (sum = dfs(e->to, min(Min, e->cap)))){ 
            e->cap -= sum;
            e->rcap->cap += sum;
            return sum;
        }
    }
    return 0;
}