PKU JudgeOnline 1274 - The Perfect Stall

問題

http://poj.org/problem?id=1274

N頭の牛とMのstallが存在しています. 各牛にはお気に入りのstallがあり, そこに入っている時しかミルクを出してくれません. 各stallには一頭の牛しか入れることはできないため, Farmer Johnはなるべく多くのミルクを手に入れるような割り当て方をしたいです.
そのような割り当て方をした時, 何頭の牛からミルクを手に入れることができるでしょうか.

解法

二部マッチングやるだけです.

ソースコード

#include <iostream>
#include <vector>
#include <cstring>
using namespace std;

struct BipartiteMatching {
    int V;  // 頂点数
    vector<vector<int> > graph; // グラフの隣接リスト表現
    vector<int> match;  // 各頂点ごとのマッチングの対応
    vector<bool> used;  // DFSの際に使用

    BipartiteMatching(int v) {
        V = v;
        graph = vector<vector<int> >(V);
        match = vector<int>(V);
        used = vector<bool>(V);
    }

    // uとvを連結にする
    void AddEdge(int u, int v) {
        graph[u].push_back(v);
        graph[v].push_back(u);
    }

    bool DFS(int v) {
        used[v] = true;
        for (int i = 0; i < graph[v].size(); i++) {
            int u = graph[v][i], w = match[u];
            if (w < 0 || (!used[w] && DFS(w))) {
                match[v] = u;
                match[u] = v;
                return true;
            }
        }
        return false;
    }

    // 二部マッチングを解く
    int Solve() {
        int res = 0;
        fill(match.begin(), match.end(), -1);
        for (int v = 0; v < V; v++) {
            if (match[v] < 0) {
                fill(used.begin(), used.end(), false);
                if (DFS(v)) {
                    res++;
                }
            }
        }
        return res;
    }
};

int N, M;
vector<vector<int> > stalls;

void Solve() {
    BipartiteMatching bm(N + M);

    for (int i = 0; i < N; i++) {
        for (int j = 0; j < stalls[i].size(); j++) {
            bm.AddEdge(i, N + stalls[i][j] - 1);
        }
    }

    cout << bm.Solve() << endl;
}

int main() {
    while (cin >> N >> M, !cin.eof()) {
        stalls = vector<vector<int> >(N);

        for (int i = 0; i < N; i++) {
            int num;
            cin >> num;
            stalls[i] = vector<int>(num);

            for (int j = 0; j < num; j++) {
                cin >> stalls[i][j];
            }
        }

        Solve();
    }

    return 0;
}

感想

最初入力の終わりまで読み込むということに気づけませんでした.