Advertisement
Guest User

Untitled

a guest
Jun 30th, 2016
66
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.75 KB | None | 0 0
  1. // Problem H. Gift Exchange Party / プレゼント交換会
  2.  
  3. #include <bits/stdc++.h>
  4. #define REP(i, n) for(auto i = 0; i < n; i++)
  5. using namespace std;
  6.  
  7. auto solve(int n, vector<int>& p, vector<vector<bool>>& g) -> void {
  8. vector<bool> used;
  9. // cur番目のノードから連結しているプレゼント数が閾値 (th) 以下のノードを深さ優先探索
  10. function<bool(int, int)> dfs = [&](int cur, int th) {
  11. // cur番目のノードのプレゼント数が閾値以下ならばプレゼント数を増やしてretrun
  12. if(p[cur] <= th) {p[cur]++; return true;}
  13. used[cur] = true;
  14. REP(prev, n) {
  15. // 探索対象のノードが見つかったならば
  16. if(!used[prev] && g[prev][cur] && dfs(prev, th)) {
  17. // 辺の向きを逆にする
  18. swap(g[prev][cur], g[cur][prev]);
  19. return true;
  20. }
  21. }
  22. return false;
  23. };
  24. // プレゼント数が最大のノードが受け取るプレゼントを貪欲的に減らす
  25. while(true) {
  26. // プレゼント数が最大のノードを探索
  27. auto max_i = distance(p.begin(), max_element(p.begin(), p.end()));
  28. used.assign(n, false);
  29. // プレゼント数が (プレゼント数の最大値 - 2) 以下のノードを探索
  30. // 見つからなければ終了
  31. if(!dfs(max_i, p[max_i] - 2)) break;
  32. // プレゼント数が最大のノードのプレゼント数を減らす
  33. p[max_i]--;
  34. }
  35. }
  36.  
  37. auto main() -> int {
  38. int n, m, ui, vi;
  39. while(cin >> n >> m, n || m) {
  40. vector<int> p(n, 0);
  41. vector<vector<bool>> g(n, vector<bool>(n, false));
  42. REP(i, m) cin >> ui >> vi, g[ui - 1][vi - 1] = true, p[vi - 1]++;
  43. solve(n, p, g);
  44. auto ans = minmax_element(p.begin(), p.end());
  45. cout << *ans.first << ' ' << *ans.second << endl;
  46. }
  47. return 0;
  48. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement