結果
問題 | No.241 出席番号(1) |
ユーザー |
![]() |
提出日時 | 2015-07-10 22:53:13 |
言語 | C++11(廃止可能性あり) (gcc 13.3.0) |
結果 |
AC
|
実行時間 | 2 ms / 2,000 ms |
コード長 | 5,652 bytes |
コンパイル時間 | 981 ms |
コンパイル使用メモリ | 88,352 KB |
実行使用メモリ | 5,248 KB |
最終ジャッジ日時 | 2024-11-30 21:22:27 |
合計ジャッジ時間 | 2,306 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge2 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 29 |
ソースコード
#define _CRT_SECURE_NO_WARNINGS//#define _GLIBCXX_DEBUG#include <complex>#include <iostream>#include <vector>#include <cmath>#include <cstdio>#include <tuple>#include <string>#include <set>#include <queue>using namespace std;typedef long long ll;//#define int ll//#define endl "\n"typedef vector<int> vi;typedef vector<vi> vvi;typedef pair<int,int> pii;#define all(c) (c).begin(), (c).end()#define loop(i,a,b) for(ll i=a; i<ll(b); i++)#define rep(i,b) loop(i,0,b)#define pb push_back#define eb emplace_back#define mp make_pair#define mt make_tupletemplate<class T> ostream & operator<<(ostream & os, vector<T> const &);template<int n, class...T> typename enable_if<(n>=sizeof...(T))>::type _ot(ostream &, tuple<T...> const &){}template<int n, class...T> typename enable_if<(n< sizeof...(T))>::type _ot(ostream & os, tuple<T...> const & t){ os << (n==0?"":" ") << get<n>(t);_ot<n+1>(os, t); }template<class...T> ostream & operator<<(ostream & os, tuple<T...> const & t){ _ot<0>(os, t); return os; }template<class T, class U> ostream & operator<<(ostream & os, pair<T,U> const & p){ return os << "(" << p.first << ", " << p.second << ") "; }template<class T> ostream & operator<<(ostream & os, vector<T> const & v){ rep(i,v.size()) os << v[i] << (i+1==(int)v.size()?"":" "); return os; }template<class T> inline bool chmax(T & x, T const & y){ return x<y ? x=y,true : false; }template<class T> inline bool chmin(T & x, T const & y){ return x>y ? x=y,true : false; }#ifdef DEBUG#define dump(...) (cerr<<#__VA_ARGS__<<" = "<<mt(__VA_ARGS__)<<" ["<<__LINE__<<"]"<<endl)#else#define dump(...)#endif// ll const mod = 1000000007;// ll const inf = 1LL<<60;/*Dinic 法で最大フローを求めるDinic(n) : コンストラクタadd_edge(src,dst,cap) : 辺を追加solve(src,dst) : src->dstへの最大フローを流す*/int const inf = 1e8;struct Dinic {public:typedef int Capacity;struct Edge;int n;vector<vector<Edge> > g;vector<int> level, iter;struct Edge {int dst;Capacity cap, cap_orig;int revEdge;bool isRev;Edge(int dst, Capacity cap, int revEdge, bool isRev):dst(dst), cap(cap), cap_orig(cap), revEdge(revEdge), isRev(isRev) {}};Dinic(int n_): n(n_), g(vector<vector<Edge> >(n_)), level(n_), iter(n_) {}void add_edge(int src, int dst, Capacity cap) {g[src].emplace_back(Edge(dst, cap, g[dst].size(), false));g[dst].emplace_back(Edge(src, 0, g[src].size() - 1, true));}// src->dstへの最大フローを流すCapacity solve(int src, int dst) {int flow = 0;while(1){bfs(src);if (level[dst] < 0) return flow;fill(all(iter), 0);int f;while ((f = dfs(src, dst, inf)) > 0) {flow += f;}}}private:void bfs(int s) {level.assign(n,-1);queue<int> q; // 辺の数でみた最短距離level[s] = 0;q.push(s);while (q.size()) {int v = q.front(); q.pop();rep(i,g[v].size()){Edge& e = g[v][i];if (e.cap > 0 && level[e.dst] < 0) {level[e.dst] = level[v] + 1;q.push(e.dst);}}}}Capacity dfs(int v, int t, int f) {if (v == t) return f;for (int &i = iter[v]; i < (int)g[v].size(); i++) {Edge &e = g[v][i];if (e.cap > 0 && level[v] < level[e.dst]) {int d = dfs(e.dst, t, min(f, e.cap));if (d > 0) {e.cap -= d;g[e.dst][e.revEdge].cap += d;return d;}}}return 0;}public:// 現在の容量を表示// フローを流した分だけ破壊的に容量が減る実装になっているvoid view(){rep(i,g.size()){rep(j,g[i].size()){Edge & e=g[i][j];if(!e.isRev) printf("%3d->%3d (flow:%d)\n", (int)i, (int)e.dst, (int)e.cap);}}}// 流れたフロー=元々の容量-現在の容量を表示void view_flow(){rep(i,g.size()){rep(j,g[i].size())if(!g[i][j].isRev){Edge& e = g[i][j];printf("%3d->%3d (flow:%d)\n", (int)i, (int)e.dst, (int)(e.cap_orig - e.cap));}}}// 各辺の流量を得たいときはこのようにする(二部マッチングの例)// void doit(){// for(int i=0;i<g.size();i++){// for(int j=0;j<g[i].size();j++)if(!g[i][j].isRev){// Edge& e = g[i][j];// int flow = e.cap_orig - e.cap;// if(flow==1){// // i-e.dstの組を用いる// }// }// }// }};signed main(){int N;while(cin >> N){Dinic g(N*2+2);int S = N*2, T = N*2+1;rep(i,N){g.add_edge(S,i,1);g.add_edge(i+N,T,1);int b;cin >> b;rep(j,N)if(j!=b){g.add_edge(i,j+N,1);}}int f = g.solve(S,T);if(f != N){puts("-1");continue;}rep(i,N){for(auto & e : g.g[i]){if(e.cap == 0){cout << e.dst-N << endl;}}}}}