結果
問題 | No.241 出席番号(1) |
ユーザー |
![]() |
提出日時 | 2023-09-19 12:26:03 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 18 ms / 2,000 ms |
コード長 | 11,412 bytes |
コンパイル時間 | 2,612 ms |
コンパイル使用メモリ | 211,188 KB |
最終ジャッジ日時 | 2025-02-16 23:33:07 |
ジャッジサーバーID (参考情報) |
judge3 / judge4 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 29 |
ソースコード
#line 1 "playspace/main.cpp"#include <bits/stdc++.h>#line 2 "library/gandalfr/graph/flow_graph.hpp"#line 7 "library/gandalfr/graph/base_graph.hpp"namespace internal {template <class Weight> struct _base_edge {int v[2];Weight cost;int id;_base_edge() {}_base_edge(int from, int to, Weight cost, int id): v{from, to}, cost(cost), id(id) {}// x から見た反対側の端点を返すint opp(int x) {if (x == v[0]) {return v[1];} else if (x == v[1]) {return v[0];} else {std::abort();}}friend std::ostream &operator<<(std::ostream &os,const _base_edge<Weight> &e) {e.print(os);return os;}protected:virtual void print(std::ostream &os) const = 0;};} // namespace internaltemplate <class Weight> struct edge : public internal::_base_edge<Weight> {using internal::_base_edge<Weight>::_base_edge;edge reverse() const {return {this->v[1], this->v[0], this->cost, this->id};}protected:void print(std::ostream &os) const override {os << this->v[0] << " " << this->v[1] << " " << this->cost;}};template <> struct edge<int> : public internal::_base_edge<int> {static inline const int cost = 1;using internal::_base_edge<int>::_base_edge;edge(int _from, int _to, int _id) : _base_edge<int>(_from, _to, 1, _id) {}edge reverse() const { return {v[1], v[0], 1, id}; }protected:void print(std::ostream &os) const override {os << this->v[0] << " " << this->v[1];}};template <class Weight, class Flow>struct flow_edge : public internal::_base_edge<Weight> {Weight res, cap;flow_edge(int from, int to, Flow res, Flow cap, int id): internal::_base_edge<Weight>(from, to, 1, id), res(res), cap(cap) {}flow_edge(int from, int to, Flow res, Flow cap, Weight cost, int id): internal::_base_edge<Weight>(from, to, cost, id), res(res), cap(cap) {}flow_edge reverse() const {return {this->v[1], this->v[0], cap - res, cap, this->cost, this->id};}// x から見た残余Flow residual(int x) const {if (x == this->v[0]) {return res;} else if (x == this->v[1]) {return cap - res;} else {std::abort();}}// x から見て残余がゼロか?Flow is_full(int x) const {if (x == this->v[0]) {return res == 0;} else if (x == this->v[1]) {return cap - res == 0;} else {std::abort();}}// x から流量を d だけ追加void add_flow(int x, Flow d) {if (x == this->v[0]) {res -= d;} else if (x == this->v[1]) {res += d;} else {std::abort();}}protected:void print(std::ostream &os) const override {os << this->v[0] << " " << this->v[1] << " " << cap - res << "/" << cap;}};namespace internal {template <typename Edge> class _base_graph {protected:int N;std::vector<std::vector<Edge *>> G;std::vector<std::unique_ptr<Edge>> E;public:_base_graph(){};_base_graph(int n) : N(n), G(n){};_base_graph(int n, int m) : N(n), G(n) { E.reserve(m); };/*** @return ノードの数*/int count_nodes() const { return N; }/*** @return 辺の数*/int count_edges() const { return E.size(); }/*** @param n ノード番号* @return ノード n からの隣接頂点のリストの const 参照*/const std::vector<Edge *> &operator[](int n) const { return G[n]; }/*** @return グラフ全体の辺のポインタのリストの const 参照*/const std::vector<std::unique_ptr<Edge>> &edges() const { return E; }void print() const {std::cout << this->N << " " << this->E.size() << std::endl;for (auto &e : this->E)std::cout << *e << std::endl;}};} // namespace internal#line 4 "library/gandalfr/graph/flow_graph.hpp"template <typename Weight, typename Flow>class flow_graph : public internal::_base_graph<flow_edge<Weight, Flow>> {public:using internal::_base_graph<flow_edge<Weight, Flow>>::_base_graph;flow_graph(const flow_graph &other) : flow_graph(other.N) {for (auto &e : other.E) {add_edge(*e);}}/*** @brief ノードの数をn個まで増やす* @param n サイズ* @attention 今のノード数より小さい数を渡したとき、変化なし*/void expand(int n) {if (n <= this->N)return;this->N = n;this->G.resize(n);}/*** @attention 辺の id は保持される*/void add_edge(const flow_edge<Weight, Flow> &e) {this->E.emplace_back(std::make_unique<flow_edge<Weight, Flow>>(e));this->G[e.v[0]].push_back(this->E.back().get());this->G[e.v[1]].push_back(this->E.back().get());}/*** @attention 辺の id は、(現在の辺の本数)番目 が振られる*/void add_edge(int from, int to, Flow capacity) {int id = (int)this->E.size();flow_edge<Weight, Flow> e(from, to, capacity, capacity, id);this->E.emplace_back(std::make_unique<flow_edge<Weight, Flow>>(e));this->G[from].push_back(this->E.back().get());this->G[to].push_back(this->E.back().get());}Flow Ford_Fulkerson(int s, int t) {static_assert(std::is_integral<Flow>::value,"Flow must be an integer type");Flow flow = 0;while (true) {std::vector<bool> vis(this->N, false);auto dfs = [&](auto self, int cur, Flow f) -> Flow {if (cur == t)return f;vis[cur] = true;for (auto &e : this->G[cur]) {if (vis[e->opp(cur)] || e->is_full(cur))continue;Flow tmp = self(self, e->opp(cur),std::min<Flow>(e->residual(cur), f));if (tmp > static_cast<Flow>(0)) {e->add_flow(cur, tmp);return tmp;}}return static_cast<Flow>(0);};Flow inc = dfs(dfs, s, std::numeric_limits<Flow>::max());if (inc == 0)break;flow += inc;}return flow;}Flow Dinic(int s, int t) {const int invalid = std::numeric_limits<int>::max();Flow flow = 0;while (true) {std::vector<int> dist(this->N, invalid);dist[s] = 0;std::queue<int> q;q.push(s);while(!q.empty()) {int cur = q.front();q.pop();for (auto &e: this->G[cur]) {int to = e->opp(cur);if (dist[to] != invalid || e->is_full(cur))continue;dist[to] = dist[cur] + 1;q.push(to);}}if (dist[t] == invalid) break;while (true) {auto dfs = [&](auto self, int cur, Flow f) -> Flow {if (cur == s)return f;for (auto &e : this->G[cur]) {int to = e->opp(cur);if (dist[to] != dist[cur] - 1)continue;Flow tmp = self(self, to,std::min<Flow>(e->residual(to), f));if (tmp > static_cast<Flow>(0)) {e->add_flow(to, tmp);return tmp;}}return static_cast<Flow>(0);};Flow inc = dfs(dfs, t, std::numeric_limits<Flow>::max());if (inc == 0)break;flow += inc;}}return flow;}};#line 8 "library/gandalfr/other/io_supporter.hpp"template <typename T>std::ostream &operator<<(std::ostream &os, const std::vector<T> &v) {for (int i = 0; i < (int)v.size(); i++)os << v[i] << (i + 1 != (int)v.size() ? " " : "");return os;}template <typename T>std::ostream &operator<<(std::ostream &os, const std::set<T> &st) {for (const T &x : st) {std::cout << x << " ";}return os;}template <typename T>std::ostream &operator<<(std::ostream &os, const std::multiset<T> &st) {for (const T &x : st) {std::cout << x << " ";}return os;}template <typename T>std::ostream &operator<<(std::ostream &os, const std::deque<T> &dq) {for (const T &x : dq) {std::cout << x << " ";}return os;}template <typename T1, typename T2>std::ostream &operator<<(std::ostream &os, const std::pair<T1, T2> &p) {os << p.first << ' ' << p.second;return os;}template <typename T>std::ostream &operator<<(std::ostream &os, std::queue<T> &q) {int sz = q.size();while (--sz) {os << q.front() << ' ';q.push(q.front());q.pop();}os << q.front();q.push(q.front());q.pop();return os;}template <typename T>std::istream &operator>>(std::istream &is, std::vector<T> &v) {for (T &in : v)is >> in;return is;}template <typename T1, typename T2>std::istream &operator>>(std::istream &is, std::pair<T1, T2> &p) {is >> p.first >> p.second;return is;}#line 4 "playspace/main.cpp"using namespace std;using ll = long long;const int INF = 1001001001;const ll INFLL = 1001001001001001001;const ll MOD = 1000000007;const ll _MOD = 998244353;#define rep(i, j, n) for(ll i = (ll)(j); i < (ll)(n); i++)#define rrep(i, j, n) for(ll i = (ll)(n-1); i >= (ll)(j); i--)#define all(a) (a).begin(),(a).end()#define debug(a) std::cerr << #a << ": " << a << std::endl#define LF cout << endl#ifdef ENABLE_MULTI_FOR#define mrep(it, mr) for(multi_iter it(mr); !it.fin(); ++it)#endiftemplate<typename T1, typename T2> inline bool chmax(T1 &a, T2 b) { return a < b && (a = b, true); }template<typename T1, typename T2> inline bool chmin(T1 &a, T2 b) { return a > b && (a = b, true); }void Yes(bool ok){ std::cout << (ok ? "Yes" : "No") << std::endl; }int main(void){int N;cin >> N;flow_graph<int, int> G(2 * N + 2, N * N);rep(i,0,N) {G.add_edge(0, i + 1, 1);G.add_edge(i + N + 1, 2 * N + 1, 1);}rep(i,0,N) {int a;cin >> a;rep(j,0,N) {if (j == a) continue;G.add_edge(i + 1, j + N + 1, 1);}}int mch = G.Dinic(0, 2 * N + 1);if (mch != N) {cout << -1 << endl;} else {vector<int> ans(N);rep(i,0,N) {for (auto &e: G[i + 1]) {if (e->is_full(i + 1)) {ans[i] = e->v[1] - N - 1;}}}cout << ans << endl;}}