QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#604442#8759. 小班课UESTC_OldEastWest#RE 0ms3608kbC++174.2kb2024-10-02 10:56:402024-10-02 10:56:41

Judging History

你现在查看的是最新测评结果

  • [2024-10-02 10:56:41]
  • 评测
  • 测评结果:RE
  • 用时:0ms
  • 内存:3608kb
  • [2024-10-02 10:56:40]
  • 提交

answer

#include <bits/stdc++.h>

namespace MCMF {
	#define INF INT_MAX

	int n, s, t, tot;
	std::vector<int> to, nxt, cap, cost, head;
	std::vector<int> dis;

	void AddEdge(int u, int v, int c, int w) {
		to[tot] = v, nxt[tot] = head[u], cap[tot] = c, cost[tot] = w, head[u] = tot++;
	}

	void Init(int _n, int _s, int _t, std::vector<std::array<int, 4> > edge) {
		n = _n, s = _s, t = _t, tot = 0;
		int m = edge.size();
		to = nxt = cap = cost = std::vector<int> (m << 1);
		head = dis = std::vector<int> (n, -1);
		for (auto [u, v, c, w] : edge) {
			AddEdge(u, v, c, w);
			AddEdge(v, u, 0, -w);
		}
	}

	std::pair<int, int> SPFA() {
		dis = std::vector<int> (n, INF);
		std::vector<int> vis(n), que;
		std::vector<std::pair<int, int> > pre(n, std::make_pair(-1, -1));
		que.emplace_back(s), dis[s] = 0, vis[s] = 1;
		for (int j = 0, u; j < que.size(); ++j) {
			u = que[j], vis[u] = 0;
			for (int i = head[u], v, c, w; ~i; i = nxt[i]) {
				v = to[i], c = cap[i], w = cost[i];
				int new_val = dis[u] + w;
				if (c && dis[v] > new_val) {
					dis[v] = new_val;
					pre[v] = std::make_pair(u, i);
					if (!vis[v]) que.emplace_back(v), vis[v] = 1;
				}
			}
		}
		if (dis[t] >= INT_MAX) return std::make_pair(0, 0);
		int min_cost = 0, max_flow = INF;
		int now = t;
		std::vector<int> all_e_idx;
		while (now != s) {
			auto [u, e_idx] = pre[now];
			now = u;
			max_flow = std::min(max_flow, cap[e_idx]);
			all_e_idx.emplace_back(e_idx);
		}
		for (int e_idx : all_e_idx) {
			min_cost += max_flow * cost[e_idx];
			cap[e_idx] -= max_flow, cap[e_idx ^ 1] += max_flow;
		}

		return std::make_pair(min_cost, max_flow);
	}

	std::pair<int, int> MCMF() {
		int min_cost = 0, max_flow = 0;
		while (true) {
			auto [new_cost, new_flow] = SPFA();
			if (!new_flow) break;
			else min_cost += new_cost, max_flow += new_flow;
		}
		return std::make_pair(min_cost, max_flow);
	}
}

void charming() {
  int n, m; std::cin >> n >> m;
  std::vector<int> b(m);
  for (int i = 0; i < m; ++i) std::cin >> b[i];

  int s = 0, t = 1, tot = 2;
  std::map<int, int> mp0, mp1, rev_mp1;
  std::vector<std::array<int, 4> > edge;
  std::vector<std::vector<int> > a(n);
  for (int i = 0; i < n; ++i) {
    mp0[i] = tot++;
    edge.emplace_back((std::array<int, 4>) {s, mp0[i], 1, 0});
  }
  for (int i = 0; i < m; ++i) {
    mp1[i] = tot;
    rev_mp1[tot++] = i;
    edge.emplace_back((std::array<int, 4>) {mp1[i], t, b[i], 0});
  }
  for (int i = 0, k; i < n; ++i) {
    std::cin >> k;
    a[i] = std::vector<int> (k);
    for (int j = 0; j < k; ++j) {
      std::cin >> a[i][j], --a[i][j];
      edge.emplace_back((std::array<int, 4>) {mp0[i], mp1[a[i][j]], 1, j});
    }
  }
  
  MCMF::Init(tot, s, t, edge);
  auto [_, ans] = MCMF::MCMF();

  std::vector<int> seq;
  {
    using namespace MCMF;

    std::vector<int> match(n, -1);
    for (int i = 0, u; i < n; ++i) {
      u = mp0[i];
      for (int j = head[u], v, c, w; ~j; j = nxt[j]) {
        v = to[j], c = cap[j], w = cost[j];
        if (!c) {
          match[i] = w;
          break;
        }
      }
    }

    std::vector<int> vis(n);
    for (int i = 0; i < n; ++i) {
      for (int j = 0; j < n; ++j) if (match[j] > -1 && !vis[j]) {
        bool ok = true;
        for (int k = 0; k < match[j]; ++k) {
          if (b[a[j][k]]) {
            ok = false;
            break;
          }
        }
        if (ok) {
          vis[j] = 1;
          seq.emplace_back(j + 1);
          --b[a[j][match[j]]];
          break;
        }
      }
    }
    for (int i = 0; i < n; ++i) if (match[i] == -1) {
      seq.emplace_back(i + 1);
    }
  }
  
  // std::vector<int> vec(n);
  // std::iota(vec.begin(), vec.end(), 0);
  // sort(vec.begin(), vec.end(), [&](int x, int y) {
  //   if (match[x] == -1) return false;
  //   else if (match[y] == -1) return false;
  //   else {
  //     return match[x] < match[y];
  //   }
  // });

  std::cout << ans << '\n';
  for (int i = 0; i < n; ++i) std::cout << seq[i] << " \n"[i == n - 1];
}

signed main() {
  std::ios_base::sync_with_stdio(false);
  std::cin.tie(NULL);
  std::cout.tie(NULL);
  int t; std::cin >> t;
  while (t--) charming();
  return 0;
}

詳細信息

Test #1:

score: 100
Accepted
time: 0ms
memory: 3608kb

input:

3
5 5
1 1 1 1 1
4 1 3 2 4
1 5
4 3 4 2 1
2 3 5
1 1
5 3
1 2 2
2 1 2
2 1 2
2 1 3
2 1 3
2 1 3
5 5
1 1 1 1 1
2 1 2
2 5 4
2 3 2
2 4 3
2 5 1

output:

5
2 4 3 5 1
5
5 1 2 3 4
5
2 3 4 5 1

result:

ok Correct!

Test #2:

score: -100
Runtime Error

input:

250
2 1
2
1 1
1 1
1 1
1
0
2 2
1 1
1 1
2 2 1
2 2
0 2
2 1 2
1 2
1 1
1
1 1
1 2
1 0
0
1 2
1 0
0
2 1
2
1 1
0
1 2
1 0
0
2 1
2
1 1
1 1
1 1
1
1 1
1 2
1 0
1 2
2 2
2 0
1 1
1 2
1 1
1
0
1 1
1
0
1 2
0 1
1 1
2 2
1 1
1 1
2 1 2
2 2
1 1
2 2 1
2 2 1
1 2
0 1
1 2
2 1
2
1 1
0
2 2
2 0
1 1
1 2
1 1
1
1 1
2 1
2
0
1 1
1 1
1
...

output:


result: