【ネットワークフロー】宇宙飛行計画


Description
W                      。                      。                E={E1,E2,…,Em},                   I={I1, I2,…In}。  Ej        I   Rj ÍI。

    Ik    ck  。  Ej               pj  。W              ,                                        。                           

     。

              ,              。

Input
   1  2     m n。m    ,n    。    m  ,            。                 ;                  。     n            。

Output
  1      ; 2      ;        

Sample Input
2 3                      
10 1 2                
25 2 3                    
5 6 7

Sample Output
1 2
1 2 3
1 7

この問題は最大の利益の翻版です......最後の案を出力するだけでいいです.
Accode:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <bitset>
using std::cin;
using std::bitset;

const char fi[] = "shut.in";
const char fo[] = "shut.out";
const int maxN = 110;
const int MAX = 0x3fffff00;
const int MIN = -MAX;

int map[maxN][maxN];
int f[maxN][maxN];
int d[maxN], cnt[maxN];
int t[maxN], ele[maxN][maxN];
bitset <maxN> expr, instr;
int N, M, n, ans, c;

  void init_file()
  {
    freopen(fi, "r", stdin);
    freopen(fo, "w", stdout);
    std::ios::sync_with_stdio(false);
  }

  void readdata()
  {
    cin >> M >> N;
    n = M + N + 2;
    for (int i = 2; i < M + 2; ++i)
    {
      cin >> c;
      ans += c;
      map[1][i] = f[1][i] = c;
      while (1)
      {
        if (cin.peek() == '
') break; cin >> c; ele[i - 1][++t[i - 1]] = c; map[i][c + M + 1] = f[i][c + M + 1] = MAX; } } for (int i = M + 2; i < n; ++i) { cin >> c; map[i][n] = f[i][n] = c; } } int Sap(int u, int Lim) { if (u == n) return Lim; int tmp = 0; for (int v = 1; v < n + 1; ++v) if (f[u][v] > 0 && d[u] == d[v] + 1) { int k = Sap(v, std::min(Lim - tmp, f[u][v])); if (k <= 0) continue; f[u][v] -= k; f[v][u] += k; if ((tmp += k) == Lim) return tmp; } if (d[1] >= n) return tmp; if ((--cnt[d[u]]) <= 0) d[1] = n; ++cnt[++d[u]]; return tmp; } void work() { cnt[0] = n; while (d[1] < n) ans -= Sap(1, MAX); if (!ans) {printf("0"); return; } expr.set(); instr.set(); int k; for (k = 0; k < n; ++k) if (!cnt[k]) break; // 。 for (int i = 2; i < n; ++i) if (d[i] < k) { if (i > M + 1) instr.reset(i - M - 1); else expr.reset(i - 1); } // 。 for (int i = 1; i < M + 1; ++i) if (expr.test(i)) printf("%d ", i); printf("
"); for (int i = 1; i < N + 1; ++i) if (instr.test(i)) printf("%d ", i); printf("
%d", ans); } int main() { init_file(); readdata(); work(); exit(0); }