Problem:
あみだくじ
PCK 君はみんなでゲーム大会をしています。このゲーム大会では、大会の最後にあみだくじで順位を入れ替えます。大会には
N
人のプレイヤーが参加しており、あみだくじには
N
本の縦棒があります。
あみだくじは、図のように
N
- 1 段の部品からできており、それぞれ 1 から
N
-1 の番号が割り当てられています。各部品は、あみだくじの一部を横方向に切り取った部分です。各部品にはいくつかの横棒が引かれていますが、部品の中の横棒はすべて同じ高さにあります。横棒同士がつながることはありません。
大会の最後に、順位の高い人から右から左の順に縦棒が割り当てられます。PCK 君は現時点で最下位なので、左端からスタートです。例えば、上図の組み立て方では、６位だったPCK 君は、このあみだくじによって４位（右から４番目の棒）に浮上することができます。
このゲームでは、最下位の人にあみだくじを組み立てる権利が与えられます。PCK 君はうまくあみだくじの部品の順番を決めて、逆転優勝を狙っています。ただし、部品を回転することはできません。
（※補足：あみだくじのたどり方について）
あみだくじのある縦棒の上端から出発して上から下へ進む。ただし、横棒がある地点ではその横棒でつながった別の縦棒に移動する。これを、縦棒の下端にたどり着くまで繰り返す。
ゲームの参加人数とあみだくじの部品の情報を入力し、PCK 君が優勝できるかどうか判定するプログラムを作成せよ。優勝できる場合、そのあみだくじの部品の並びを１つ出力せよ。ただし、そのような並べ方が複数ある場合は、与えられた部品の番号で辞書順最小のものを出力せよ。
Input
入力は以下の形式で与えられる。
N
b
1,1
b
1,2
...
b
1,N−1
b
2,1
b
2,2
...
b
2,N−1
:
b
N−1,1
b
N−1,2
...
b
N−1,N−1
１行目に大会の参加者数
N
(2 ≤
N
≤ 500) が与えられる。続く
N
-1 行に
i
番目の部品の横棒の情報が与えられる。
b
i,j
が 1 であるとき、
i
番目の部品の、左から
j
本目の縦棒から
j
+1 番目の縦棒へ横棒が引かれていることを表す。
b
i,j
が 0 であるとき、
i
番目の部品の、左から
j
本目の縦棒から
j
+1 番目の縦棒へ横棒は引かれていないことを表す。
b
i,j
が 1 であるとき、
b
i,j+1
が 1 となるような部品は与えられない。また、横棒の総数は 10000 を越えない。
Output
PCK 君が優勝できる場合，１行目に「yes」と出力する。続く
N
-1 行に、あみだくじの上から順に、部品の番号の並びを出力する。そのような並びが複数ある場合、辞書順最小である並びを出力する。PCK 君が優勝できない場合、１行に「no」と出力する。
Sample Input 1
6
1 0 0 0 1
1 0 1 0 1
0 1 0 1 0
0 0 0 1 0
0 1 0 0 1
Sample Output 1
yes
1
3
2
4
5
Sample Input 2
5
0 1 0 1
0 1 0 1
1 0 1 0
1 0 0 1
Sample Output 2
yes
4
1
3
2
4 1 3 2 と 4 2 3 1 の２通りの組み立て方が可能だが、辞書順で小さい方の 4 1 3 2 を出力する。
Sample Input 3
5
1 0 0 1
0 1 0 1
1 0 0 0
0 1 0 1
Sample Output 3
no

Submitted solutions:

code_snippet: #include <cstdio>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <cfloat>
#include <cstring>
#include <map>
#include <utility>
#include <set>
#include <iostream>
#include <memory>
#include <string>
#include <vector>
#include <list>
#include <algorithm>
#include <functional>
#include <sstream>
#include <complex>
#include <stack>
#include <queue>
#include <unordered_set>
#include <unordered_map>
#include <array>
#include <cassert>
#include <bitset>
using namespace std;
using LL = long long;

struct Bipartite_Matching
{
	vector< vector< int > > graph;
	vector< int > match, alive, used;
	int timestamp;

	Bipartite_Matching(int n)
	{
		timestamp = 0;
		graph.resize(n);
		alive.assign(n, 1);
		used.assign(n, 0);
		match.assign(n, -1);
	}

	void add_edge(int u, int v)
	{
		graph[u].push_back(v);
		graph[v].push_back(u);
	}

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

	int bipartite_matching()
	{
		int ret = 0;
		for (int i = 0; i < graph.size(); i++) {
			if (alive[i] == 0) continue;
			if (match[i] == -1) {
				++timestamp;
				ret += dfs(i);
			}
		}
		return (ret);
	}
};

struct Lexicographically_Matching : Bipartite_Matching
{
	Lexicographically_Matching(int n) : Bipartite_Matching(n) {}

	int back(int k)   // 押し戻す
	{
		match[match[k]] = -1;
		match[k] = -1;
		++timestamp;
		dfs(k);
		return (match[k]);
	}

	void decide(int k) // 決める
	{
		alive[match[k]] = 0;
		alive[k] = 0;
	}
};

int main(void)
{
	int N;
	cin >> N;
	--N;
	Lexicographically_Matching lm(N + N);
	for (int i = 0; i < N; ++i)
	{
		for (int j = 0; j < N; ++j)
		{
			int b;
			cin >> b;
			if (b)
			{
				lm.add_edge(j, i + N);
			}
		}
	}
	int ans = lm.bipartite_matching();
	if (ans < N)
	{
		cout << "no\n";
		return 0;
	}
	cout << "yes\n";
	for (int i = 0; i < N; ++i)
	{
		if (lm.match[i] >= 0)
		{
			lm.back(i);
			lm.decide(i);
		}
	}
	for (int i = 0; i < N; ++i)
	{
		cout << lm.match[i] + 1 - N << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 3612
final_rank: 12

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <map>
#include <queue>
#include <set>
using namespace std;
typedef long long ll;
#define rep(i, n) for(int i = 0; i < (n); i++)

template<class T>
using vi = vector<T>;

template<class T>
using vii = vector<vi<T>>;

template<class T>
using viii = vector<vii<T>>;


struct Dinic {
    struct edge {
        int to, rev; ll cap;
        edge(int t, int r, ll c) : to(t), rev(r), cap(c) {}
    };
    int n;
    vii<edge> to;
    vi<int> dist, iter;
    const ll inf = 1e18;
    Dinic(int n_) : n(n_), to(n_), dist(n_), iter(n_) {}

    void addedge(int u, int v, ll c) {
        int su = (int)to[u].size();
        int sv = (int)to[v].size();
        to[u].push_back({ v, sv, c });
        to[v].push_back({ u, su, 0 });
    }

    void bfs(int s) {
        dist.assign(n, -1);
        dist[s] = 0;
        queue<int> q;
        q.push(s);
        while (!q.empty()) {
            int v = q.front();
            q.pop();
            for (edge& nv : to[v]) {
                if (nv.cap == 0 || dist[nv.to] != -1) continue;
                dist[nv.to] = dist[v] + 1;
                q.push(nv.to);
            }
        }
    }

    ll dfs(int v, int t, ll f) {
        if (v == t) return f;
        int sv = (int)to[v].size();
        for (int& i = iter[v]; i < sv; i++) {
            edge& nv = to[v][i];
            if (nv.cap == 0 || dist[nv.to] <= dist[v]) continue;
            ll nf = dfs(nv.to, t, min(f, nv.cap));
            if (nf > 0) {
                nv.cap -= nf;
                to[nv.to][nv.rev].cap += nf;
                return nf;
            }
        }
        return 0;
    }

    ll maxflow(int s, int t) {
        ll res = 0, flow = 0;
        while (true) {
            bfs(s);
            if (dist[t] < 0) break;
            iter.assign(n, 0);
            do {
                flow = dfs(s, t, inf);
                res += flow;

            } while (flow);
        };
        return res;
    }
};

int main()
{    
    int n;
    cin >> n;
    n--;
    vii<int> b(n, vi<int>(n));
    rep(i, n) rep(j, n) cin >> b[i][j];
    vii<int> tb = b;

    vi<int> ans(n);
    int S = 2 * n, T = 2 * n + 1;
    rep(j, n) {
        Dinic dn(2 * n + 2);
        rep(k, j) dn.addedge(k, ans[k] + n, 1);
        for (int k = j + 1; k < n; k++) {
            rep(i, n) if(b[i][k]) dn.addedge(k, i + n, 1);
        }

        rep(k, n) dn.addedge(S, k, 1);
        rep(i, n) dn.addedge(i + n, T, 1);

        int flow = 0;
        rep(i, n) {
            if (b[i][j]) {
                dn.addedge(j, i + n, 1);
                flow += dn.maxflow(S, T);
                if (flow == n) {
                    ans[j] = i;
                    for(int k = i + 1; k < n; k++) b[i][k] = 0;
                    break;
                }
            }
        }

        if (flow != n) {
            cout << "no" << endl;
            return 0;
        }
    }


    cout << "yes" << endl;
    rep(i, n) cout << ans[i] + 1 << endl;
    //rep(i, n) rep(j, n) cout << tb[ans[i]][j] << " \n"[j == n - 1];
    return 0;
}
accuracy: 1
time_ms: 150
memory_kb: 5824
final_rank: 18

code_snippet: #line 1 "a.cpp"
#include<iostream>
#include<vector>
using namespace std;
#line 1 "/home/kotatsugame/library/graph/MCF.cpp"
//Minimum Cost Flow O(FE log V)
#include<algorithm>
#include<utility>
#line 5 "/home/kotatsugame/library/graph/MCF.cpp"
#include<queue>
#include<limits>
template<typename T>
struct MCF{
	struct edge{
		int to,rev,cap;
		T cost;
	};
	vector<vector<edge> >G;
	vector<T>h,d;
	vector<int>pv,pe;
	MCF(int n_=0):G(n_),h(n_,0),d(n_),pv(n_),pe(n_){}
	void add_edge(int from,int to,int cap,T cost)
	{
		G[from].push_back({to,(int)G[to].size(),cap,cost});
		G[to].push_back({from,(int)G[from].size()-1,0,-cost});
	}
	T min_cost_flow(int s,int t,int f)//ans or -1
	{
		T ret=0;
		while(f>0)
		{
			priority_queue<pair<T,int>,vector<pair<T,int> >,greater<pair<T,int> > >P;
			fill(d.begin(),d.end(),numeric_limits<T>::max());
			d[s]=0;
			P.push(make_pair(0,s));
			while(!P.empty())
			{
				pair<T,int>p=P.top();P.pop();
				if(d[p.second]<p.first)continue;
				for(int i=0;i<G[p.second].size();i++)
				{
					edge&e=G[p.second][i];
					if(e.cap>0&&d[e.to]>d[p.second]+e.cost+h[p.second]-h[e.to])
					{
						d[e.to]=d[p.second]+e.cost+h[p.second]-h[e.to];
						pv[e.to]=p.second;
						pe[e.to]=i;
						P.push(make_pair(d[e.to],e.to));
					}
				}
			}
			if(d[t]==numeric_limits<T>::max())return -1;
			for(int u=0;u<G.size();u++)h[u]+=d[u];
			int d=f;
			for(int u=t;u!=s;u=pv[u])d=min(d,G[pv[u]][pe[u]].cap);
			f-=d;
			ret+=d*h[t];
			for(int u=t;u!=s;u=pv[u])
			{
				G[pv[u]][pe[u]].cap-=d;
				G[u][G[pv[u]][pe[u]].rev].cap+=d;
			}
		}
		return ret;
	}
};
#line 5 "a.cpp"
int N;
bool exs[500][500];
bool out[500];
const int B=5;
long p500[B];
main()
{
	p500[0]=1;
	for(int i=1;i<B;i++)p500[i]=p500[i-1]*500;
	cin>>N;
	for(int i=0;i<N-1;i++)
	{
		for(int j=0;j<N-1;j++)
		{
			int c;cin>>c;
			exs[i][j]=c==1;
		}
	}
	vector<int>ans;
	for(int tm=0;tm<N-1;tm+=B)
	{
		MCF<long>P(2*N);
		int st=2*(N-1),go=st+1;
		for(int i=0;i<N-1;i++)if(!out[i])
		{
			P.add_edge(st,i,1,0);
			for(int j=tm;j<N-1;j++)if(exs[i][j])
			{
				P.add_edge(i,N-1+j,1,j<tm+B?i*p500[tm+B-j-1]:0);
			}
		}
		for(int j=tm;j<N-1;j++)P.add_edge(N-1+j,go,1,0);
		long ret=P.min_cost_flow(st,go,N-1-tm);
		if(ret==-1)break;
		for(int j=0;j<B&&tm+j<N-1;j++)
		{
			int id=ret/p500[B-1-j]%500;
			ans.push_back(id+1);
			out[id]=true;
		}
	}
	if(ans.size()<N-1)cout<<"no"<<endl;
	else
	{
		cout<<"yes"<<endl;
		for(int id:ans)cout<<id<<endl;
	}
}
accuracy: 1
time_ms: 1150
memory_kb: 3764
final_rank: 19

code_snippet: #include<bits/stdc++.h>

using namespace std;

using int64 = long long;
const int mod = 1e9 + 7;
// const int mod = 998244353;

const int64 infll = (1LL << 62) - 1;
const int inf = (1 << 30) - 1;

struct IoSetup {
  IoSetup() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(10);
    cerr << fixed << setprecision(10);
  }
} iosetup;


template< typename T1, typename T2 >
ostream &operator<<(ostream &os, const pair< T1, T2 > &p) {
  os << p.first << " " << p.second;
  return os;
}

template< typename T1, typename T2 >
istream &operator>>(istream &is, pair< T1, T2 > &p) {
  is >> p.first >> p.second;
  return is;
}

template< typename T >
ostream &operator<<(ostream &os, const vector< T > &v) {
  for(int i = 0; i < (int) v.size(); i++) {
    os << v[i] << (i + 1 != v.size() ? " " : "");
  }
  return os;
}

template< typename T >
istream &operator>>(istream &is, vector< T > &v) {
  for(T &in : v) is >> in;
  return is;
}

template< 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); }

template< typename T = int64 >
vector< T > make_v(size_t a) {
  return vector< T >(a);
}

template< typename T, typename... Ts >
auto make_v(size_t a, Ts... ts) {
  return vector< decltype(make_v< T >(ts...)) >(a, make_v< T >(ts...));
}

template< typename T, typename V >
typename enable_if< is_class< T >::value == 0 >::type fill_v(T &t, const V &v) {
  t = v;
}

template< typename T, typename V >
typename enable_if< is_class< T >::value != 0 >::type fill_v(T &t, const V &v) {
  for(auto &e : t) fill_v(e, v);
}

template< typename F >
struct FixPoint : F {
  FixPoint(F &&f) : F(forward< F >(f)) {}

  template< typename... Args >
  decltype(auto) operator()(Args &&... args) const {
    return F::operator()(*this, forward< Args >(args)...);
  }
};

template< typename F >
inline decltype(auto) MFP(F &&f) {
  return FixPoint< F >{forward< F >(f)};
}

/**
 * @brief Bipartite-Flow(二部グラフのフロー)
 */
struct BipartiteFlow {
  size_t n, m, time_stamp;
  vector< vector< int > > graph;
  vector< int > match_l, match_r, dist, used, alive;

  explicit BipartiteFlow(size_t n, size_t m) :
      n(n), m(m), graph(n), match_l(n, -1), match_r(m, -1), used(n), alive(n, 1), time_stamp(0) {}

  void add_edge(int u, int v) {
    graph[u].push_back(v);
  }

  void build_augment_path() {
    queue< int > que;
    dist.assign(graph.size(), -1);
    for(int i = 0; i < n; i++) {
      if(match_l[i] == -1) {
        que.emplace(i);
        dist[i] = 0;
      }
    }
    while(!que.empty()) {
      int a = que.front();
      que.pop();
      for(auto &b : graph[a]) {
        int c = match_r[b];
        if(c >= 0 && dist[c] == -1) {
          dist[c] = dist[a] + 1;
          que.emplace(c);
        }
      }
    }
  }

  bool find_min_dist_augment_path(int a) {
    used[a] = time_stamp;
    for(auto &b : graph[a]) {
      int c = match_r[b];
      if(c < 0 || (used[c] != time_stamp && dist[c] == dist[a] + 1 && find_min_dist_augment_path(c))) {
        match_r[b] = a;
        match_l[a] = b;
        return true;
      }
    }
    return false;
  }

  bool find_augment_path(int a) {
    used[a] = time_stamp;
    for(auto &b : graph[a]) {
      int c = match_r[b];
      if(c < 0 || (alive[c] == 1 && used[c] != time_stamp && find_augment_path(c))) {
        match_r[b] = a;
        match_l[a] = b;
        return true;
      }
    }
    return false;
  }


  vector< pair< int, int > > max_matching() {
    for(;;) {
      build_augment_path();
      ++time_stamp;
      int flow = 0;
      for(int i = 0; i < n; i++) {
        if(match_l[i] == -1) flow += find_min_dist_augment_path(i);
      }
      if(flow == 0) break;
    }
    vector< pair< int, int > > ret;
    for(int i = 0; i < n; i++) {
      if(match_l[i] >= 0) ret.emplace_back(i, match_l[i]);
    }
    return ret;
  }

  vector< pair< int, int > > lex_min_max_matching() {
    max_matching();
    vector< pair< int, int > > es;
    for(int i = 0; i < n; i++) {
      if(match_l[i] == -1 || alive[i] == 0) {
        continue;
      }
      match_r[match_l[i]] = -1;
      match_l[i] = -1;
      ++time_stamp;
      find_augment_path(i);
      alive[i] = 0;
      es.emplace_back(i, match_l[i]);
    }
    return es;
  }
};


int main() {
  int N;
  cin >> N;
  --N;
  BipartiteFlow flow(N, N);
  for(int i = 0; i < N; i++) {
    for(int j = 0; j < N; j++) {
      int x;
      cin >> x;
      if(x) flow.add_edge(j, i);
    }
  }
  auto v = flow.lex_min_max_matching();
  if(v.size() < N) {
    cout << "no\n";
  } else {
    cout << "yes\n";
    for(auto &p : v) cout << p.second + 1 << "\n";
  }
}
accuracy: 1
time_ms: 10
memory_kb: 3308
final_rank: 4

code_snippet: #include<bits/stdc++.h>

using namespace std;

using int64 = long long;
const int mod = 1e9 + 7;
// const int mod = 998244353;

const int64 infll = (1LL << 62) - 1;
const int inf = (1 << 30) - 1;

struct IoSetup {
  IoSetup() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(10);
    cerr << fixed << setprecision(10);
  }
} iosetup;


template< typename T1, typename T2 >
ostream &operator<<(ostream &os, const pair< T1, T2 > &p) {
  os << p.first << " " << p.second;
  return os;
}

template< typename T1, typename T2 >
istream &operator>>(istream &is, pair< T1, T2 > &p) {
  is >> p.first >> p.second;
  return is;
}

template< typename T >
ostream &operator<<(ostream &os, const vector< T > &v) {
  for(int i = 0; i < (int) v.size(); i++) {
    os << v[i] << (i + 1 != v.size() ? " " : "");
  }
  return os;
}

template< typename T >
istream &operator>>(istream &is, vector< T > &v) {
  for(T &in : v) is >> in;
  return is;
}

template< 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); }

template< typename T = int64 >
vector< T > make_v(size_t a) {
  return vector< T >(a);
}

template< typename T, typename... Ts >
auto make_v(size_t a, Ts... ts) {
  return vector< decltype(make_v< T >(ts...)) >(a, make_v< T >(ts...));
}

template< typename T, typename V >
typename enable_if< is_class< T >::value == 0 >::type fill_v(T &t, const V &v) {
  t = v;
}

template< typename T, typename V >
typename enable_if< is_class< T >::value != 0 >::type fill_v(T &t, const V &v) {
  for(auto &e : t) fill_v(e, v);
}

template< typename F >
struct FixPoint : F {
  FixPoint(F &&f) : F(forward< F >(f)) {}

  template< typename... Args >
  decltype(auto) operator()(Args &&... args) const {
    return F::operator()(*this, forward< Args >(args)...);
  }
};

template< typename F >
inline decltype(auto) MFP(F &&f) {
  return FixPoint< F >{forward< F >(f)};
}

/**
 * @brief Bipartite-Graph(二部グラフ)
 * @docs docs/bipartite-graph.md
 */
struct BipartiteGraph {
  size_t n, m, time_stamp;
  vector< vector< int > > graph;
  vector< int > match_l, match_r, dist, used, alive;

  explicit BipartiteGraph(size_t n, size_t m) :
      n(n), m(m), graph(n), match_l(n, -1), match_r(m, -1), used(n), alive(n, 1), time_stamp(0) {}

  void add_edge(int u, int v) {
    graph[u].push_back(v);
  }

  void build_augment_path() {
    queue< int > que;
    dist.assign(graph.size(), -1);
    for(int i = 0; i < n; i++) {
      if(match_l[i] == -1) {
        que.emplace(i);
        dist[i] = 0;
      }
    }
    while(!que.empty()) {
      int a = que.front();
      que.pop();
      for(auto &b : graph[a]) {
        int c = match_r[b];
        if(c >= 0 && dist[c] == -1) {
          dist[c] = dist[a] + 1;
          que.emplace(c);
        }
      }
    }
  }

  bool find_min_dist_augment_path(int a) {
    used[a] = time_stamp;
    for(auto &b : graph[a]) {
      int c = match_r[b];
      if(c < 0 || (used[c] != time_stamp && dist[c] == dist[a] + 1 && find_min_dist_augment_path(c))) {
        match_r[b] = a;
        match_l[a] = b;
        return true;
      }
    }
    return false;
  }

  bool find_augment_path(int a) {
    used[a] = time_stamp;
    for(auto &b : graph[a]) {
      int c = match_r[b];
      if(c < 0 || (alive[c] == 1 && used[c] != time_stamp && find_augment_path(c))) {
        match_r[b] = a;
        match_l[a] = b;
        return true;
      }
    }
    return false;
  }


  vector< pair< int, int > > max_matching() {
    for(;;) {
      build_augment_path();
      ++time_stamp;
      int flow = 0;
      for(int i = 0; i < n; i++) {
        if(match_l[i] == -1) flow += find_min_dist_augment_path(i);
      }
      if(flow == 0) break;
    }
    vector< pair< int, int > > ret;
    for(int i = 0; i < n; i++) {
      if(match_l[i] >= 0) ret.emplace_back(i, match_l[i]);
    }
    return ret;
  }

  vector< pair< int, int > > lex_min_max_matching() {
    max_matching();
    for(auto &vs : graph) sort(begin(vs), end(vs));
    vector< pair< int, int > > es;
    for(int i = 0; i < n; i++) {
      if(match_l[i] == -1 || alive[i] == 0) {
        continue;
      }
      match_r[match_l[i]] = -1;
      match_l[i] = -1;
      ++time_stamp;
      find_augment_path(i);
      alive[i] = 0;
      es.emplace_back(i, match_l[i]);
    }
    return es;
  }

};


int main() {
  int N;
  cin >> N;
  --N;
  BipartiteGraph flow(N, N);
  for(int i = 0; i < N; i++) {
    for(int j = 0; j < N; j++) {
      int x;
      cin >> x;
      if(x) flow.add_edge(j, i);
    }
  }
  auto v = flow.lex_min_max_matching();
  if(v.size() < N) {
    cout << "no\n";
  } else {
    cout << "yes\n";
    for(auto &p : v) cout << p.second + 1 << "\n";
  }
}
accuracy: 1
time_ms: 10
memory_kb: 3268
final_rank: 2

code_snippet: #include<bits/stdc++.h>

using namespace std;

using int64 = long long;
const int mod = 1e9 + 7;
// const int mod = 998244353;

const int64 infll = (1LL << 62) - 1;
const int inf = (1 << 30) - 1;

struct IoSetup {
  IoSetup() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(10);
    cerr << fixed << setprecision(10);
  }
} iosetup;


template< typename T1, typename T2 >
ostream &operator<<(ostream &os, const pair< T1, T2 > &p) {
  os << p.first << " " << p.second;
  return os;
}

template< typename T1, typename T2 >
istream &operator>>(istream &is, pair< T1, T2 > &p) {
  is >> p.first >> p.second;
  return is;
}

template< typename T >
ostream &operator<<(ostream &os, const vector< T > &v) {
  for(int i = 0; i < (int) v.size(); i++) {
    os << v[i] << (i + 1 != v.size() ? " " : "");
  }
  return os;
}

template< typename T >
istream &operator>>(istream &is, vector< T > &v) {
  for(T &in : v) is >> in;
  return is;
}

template< 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); }

template< typename T = int64 >
vector< T > make_v(size_t a) {
  return vector< T >(a);
}

template< typename T, typename... Ts >
auto make_v(size_t a, Ts... ts) {
  return vector< decltype(make_v< T >(ts...)) >(a, make_v< T >(ts...));
}

template< typename T, typename V >
typename enable_if< is_class< T >::value == 0 >::type fill_v(T &t, const V &v) {
  t = v;
}

template< typename T, typename V >
typename enable_if< is_class< T >::value != 0 >::type fill_v(T &t, const V &v) {
  for(auto &e : t) fill_v(e, v);
}

template< typename F >
struct FixPoint : F {
  FixPoint(F &&f) : F(forward< F >(f)) {}

  template< typename... Args >
  decltype(auto) operator()(Args &&... args) const {
    return F::operator()(*this, forward< Args >(args)...);
  }
};

template< typename F >
inline decltype(auto) MFP(F &&f) {
  return FixPoint< F >{forward< F >(f)};
}

/**
 * @brief Bipartite-Matching(二部グラフの最大マッチング)
 * @docs docs/bipartite-matching.md
 */
struct BipartiteMatching {
  vector< vector< int > > graph;
  vector< int > match, alive, used;
  int timestamp;

  explicit BipartiteMatching(int n) : graph(n), alive(n, 1), used(n, 0), match(n, -1), timestamp(0) {}

  void add_edge(int u, int v) {
    graph[u].push_back(v);
    graph[v].push_back(u);
  }

  bool augment(int idx) {
    used[idx] = timestamp;
    for(auto &to : graph[idx]) {
      int to_match = match[to];
      if(alive[to] == 0) continue;
      if(to_match == -1 || (used[to_match] != timestamp && augment(to_match))) {
        match[idx] = to;
        match[to] = idx;
        return true;
      }
    }
    return false;
  }

  int bipartite_matching() {
    int ret = 0;
    for(int i = 0; i < (int) graph.size(); i++) {
      if(alive[i] == 0) continue;
      if(match[i] == -1) {
        ++timestamp;
        ret += augment(i);
      }
    }
    return ret;
  }

  int add_vertex(int idx) {
    alive[idx] = 1;
    ++timestamp;
    return augment(idx);
  }

  int erase_vertex(int idx) {
    alive[idx] = 0;
    if(match[idx] == -1) {
      return 0;
    }
    match[match[idx]] = -1;
    ++timestamp;
    int ret = augment(match[idx]);
    match[idx] = -1;
    return ret - 1;
  }

  int lex_min_bipartite_matching() {
    for(auto &vs : graph) {
      sort(begin(vs), end(vs));
    }
    int ret = bipartite_matching();
    for(int i = 0; i < (int) graph.size(); i++) {
      if(alive[i] == 0 || match[i] == -1) {
        continue;
      }
      match[match[i]] = -1;
      match[i] = -1;
      ++timestamp;
      augment(i);
      alive[match[i]] = 0;
      alive[i] = 0;
    }
    return ret;
  }

  void output() const {
    for(int i = 0; i < (int) graph.size(); i++) {
      if(i < match[i]) {
        cout << i << "-" << match[i] << endl;
      }
    }
  }
};


int main() {
  int N;
  cin >> N;
  --N;
  BipartiteMatching flow(N + N);
  for(int i = 0; i < N; i++) {
    for(int j = 0; j < N; j++) {
      int x;
      cin >> x;
      if(x) flow.add_edge(j, N + i);
    }
  }
  int v = flow.lex_min_bipartite_matching();
  if(v < N) {
    cout << "no\n";
  } else {
    cout << "yes\n";
    for(int i = 0; i < N; i++) {
      cout << flow.match[i] - N + 1 << "\n";
    }
  }
}
accuracy: 1
time_ms: 10
memory_kb: 3336
final_rank: 6

code_snippet: #include <iostream>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <numeric>
#include <bitset>
#include <cmath>

static const int MOD = 1000000007;
using ll = long long;
using u32 = unsigned;
using u64 = unsigned long long;
using namespace std;

template<class T> constexpr T INF = ::numeric_limits<T>::max()/32*15+208;

class Bipartite_Matching {
protected:
    vector<vector<int>> G;
    vector<int> used, alive;
    int t;
    int l, r;
public:
    vector<int> match;
    explicit Bipartite_Matching(int l, int r): l(l), r(r), t(0), G(l+r), used(l+r, 0), alive(l+r, -1), match(l+r, -1) {};

    void add_edge(int a, int b){
        G[a].emplace_back(b+l);
        G[b+l].emplace_back(a);
    }

    bool dfs(int x){
        used[x] = t;
        for (auto &&i : G[x]) {
            int w = match[i];
            if(alive[i] == 0) continue;
            if(w == -1 || (used[w] != t && dfs(w))){
                match[x] = i;
                match[i] = x;
                return true;
            }
        }
        return false;
    }

    int matching() {
        int ans = 0;
        for (int i = 0; i < G.size(); ++i) {
            if(alive[i] == 0) continue;
            if(match[i] == -1) {
                ++t;
                ans += dfs(i);
            }
        }
        return ans;
    }
};

class Bipartite_Matching_LexMin : public Bipartite_Matching {
public:
    using Bipartite_Matching::Bipartite_Matching;

    int solve_LexMin() {
        int res = matching();
        for (int i = 0; i < l; ++i) {
            if(!~match[i]) continue;
            match[match[i]] = -1;
            match[i] = -1;
            ++t;
            dfs(i);
            alive[match[i]] = 0;
            alive[i] = 0;
        }
        return res;
    }
};

int main() {
    int n;
    scanf("%d", &n); n--;
    Bipartite_Matching_LexMin G(n, n);
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            int x;
            scanf("%d", &x);
            if(x){
                G.add_edge(j, i);
            }
        }
    }
    auto matching = G.solve_LexMin();
    if(matching != n) {
        puts("no");
        return 0;
    }
    puts("yes");
    for (int i = 0; i < n; ++i) {
        printf("%d\n", G.match[i]-n+1);
    }
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3388
final_rank: 8

code_snippet: #define _USE_MATH_DEFINES
#include <bits/stdc++.h>
using namespace std;
#define FOR(i,m,n) for(int i=(m);i<(n);++i)
#define REP(i,n) FOR(i,0,n)
#define ALL(v) (v).begin(),(v).end()
using ll = long long;
template <typename T> using posteriority_queue = priority_queue<T, vector<T>, greater<T> >;
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3fLL;
const double EPS = 1e-8;
const int MOD = 1000000007;
// const int MOD = 998244353;
const int dy[] = {1, 0, -1, 0}, dx[] = {0, -1, 0, 1};
// const int dy[] = {1, 1, 0, -1, -1, -1, 0, 1}, dx[] = {0, -1, -1, -1, 0, 1, 1, 1};
template <typename T, typename U> inline bool chmax(T &a, U b) { return a < b ? (a = b, true) : false; }
template <typename T, typename U> inline bool chmin(T &a, U b) { return a > b ? (a = b, true) : false; }
template <typename T> void unique(vector<T> &a) { a.erase(unique(ALL(a)), a.end()); }
struct IOSetup {
  IOSetup() {
    cin.tie(nullptr);
    ios_base::sync_with_stdio(false);
    cout << fixed << setprecision(20);
  }
} iosetup;

struct BipartiteMatching {
  vector<int> match;

  BipartiteMatching(int n) : n(n), graph(n), match(n, -1), used(n, -1), alive(n, true) {}

  void add_edge(int u, int v) {
    graph[u].emplace_back(v);
    graph[v].emplace_back(u);
  }

  int solve() {
    int res = 0;
    REP(i, n) {
      if (alive[i] && match[i] == -1) {
        ++timestamp;
        if (dfs(i)) ++res;
      }
    }
    return res;
  }

  int push_back(int ver) {
    if (match[ver] != -1) match[match[ver]] = -1;
    match[ver] = -1;
    ++timestamp;
    dfs(ver);
    return match[ver];
  }

  void fix(int ver) {
    alive[ver] = false;
    if (match[ver] != -1) alive[match[ver]] = false;
  }

  int enable(int ver) {
    if (alive[ver]) return 0;
    alive[ver] = true;
    ++timestamp;
    return dfs(ver) ? 1 : 0;
  }

  int disable(int ver) {
    if (!alive[ver]) return 0;
    alive[ver] = false;
    if (match[ver] == -1) return 0;
    match[match[ver]] = -1;
    ++timestamp;
    int tmp = match[ver];
    match[ver] = -1;
    return dfs(tmp) ? 0 : -1;
  }

private:
  int n, timestamp = -1;
  vector<vector<int> > graph;
  vector<int> used;
  vector<bool> alive;

  bool dfs(int ver) {
    used[ver] = timestamp;
    for (int e : graph[ver]) if (alive[e]) {
      int tmp = match[e];
      if (tmp == -1 || (used[tmp] < timestamp && dfs(tmp))) {
        match[ver] = e;
        match[e] = ver;
        return true;
      }
    }
    return false;
  }
};

int main() {
  int n; cin >> n; --n;
  BipartiteMatching bm(n << 1);
  REP(i, n) REP(j, n) {
    int b; cin >> b;
    if (b == 1) bm.add_edge(j, n + i);
  }
  if (bm.solve() == n) {
    cout << "yes\n";
  } else {
    cout << "no\n";
    return 0;
  }
  REP(i, n) {
    cout << bm.push_back(i) - n + 1 << '\n';
    bm.fix(i);
  }
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3348
final_rank: 7

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll=long long;
using pll=pair<ll,ll>;
const ll LINF=0x1fffffffffffffff;
#define _name3(_1,_2,_3,name,...) name
#define _rep1(n) for(ll i=0;i<(n);++i)
#define _rep2(i,n) for(ll i=0;i<(n);++i)
#define _rep3(i,a,b) for(ll i=(a);i<(b);++i)
#define rep(...) _name3(__VA_ARGS__,_rep3,_rep2,_rep1)(__VA_ARGS__)
#define rrep(i,a,b) for(ll i=(b)-1;i>=(a);i--)
#define each(i,a) for(auto &i:a)
#define sum(a) accumulate(range(a),0LL)
#define range(i) (i).begin(),(i).end()
template<class T> inline constexpr bool chmin(T &mn,const T &cnt){if(mn>cnt){mn=cnt;return 1;}else return 0;}
template<class T> inline constexpr bool chmax(T &mx,const T &cnt){if(mx<cnt){mx=cnt;return 1;}else return 0;}

struct Bipartite_Matching
{
  vector< vector< int > > graph;
  vector< int > match, alive, used;
  int timestamp;
 
  Bipartite_Matching(int n)
  {
    timestamp = 0;
    graph.resize(n);
    alive.assign(n, 1);
    used.assign(n, 0);
    match.assign(n, -1);
  }
 
  void add_edge(int u, int v)
  {
    graph[u].push_back(v);
    graph[v].push_back(u);
  }
 
  bool dfs(int v)
  {
    used[v] = timestamp;
    for(int i = 0; i < graph[v].size(); i++) {
      int u = graph[v][i], w = match[u];
      if(alive[u] == 0) continue;
      if(w == -1 || (used[w] != timestamp && dfs(w))) {
        match[v] = u;
        match[u] = v;
        return (true);
      }
    }
    return (false);
  }
 
  int bipartite_matching()
  {
    int ret = 0;
    for(int i = 0; i < graph.size(); i++) {
      if(alive[i] == 0) continue;
      if(match[i] == -1) {
        ++timestamp;
        ret += dfs(i);
      }
    }
    return (ret);
  } 
};
struct Lexicographically_Matching : Bipartite_Matching
{
  Lexicographically_Matching(int n) : Bipartite_Matching(n) {}

  int back(int k)   // 押し戻す
  {
    match[match[k]] = -1;
    match[k] = -1;
    ++timestamp;
    dfs(k);
    return (match[k]);
  }

  void decide(int k) // 決める
  {
    alive[match[k]] = 0;
    alive[k] = 0;
  }
};
int main() {
    int n;
    cin>>n;
    n--;
    vector<vector<int>>a(n,vector<int>(n));
    each(i,a)each(j,i)cin>>j;
    Lexicographically_Matching match(n*2);
    rep(n)rep(j,n)if(a[i][j])match.add_edge(j,i+n);
    each(i,match.graph)sort(i.begin(),i.end());
    match.bipartite_matching();
    rep(n)if(match.match[i]==-1)return puts("no")&0;
    rep(n){
        match.back(i);
        match.decide(i);
    }
    puts("yes");
    rep(n)cout<<match.match[i]+1-n<<endl;
}
accuracy: 1
time_ms: 20
memory_kb: 4064
final_rank: 16

code_snippet: #include <vector>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
int main() {
	int N;
	cin >> N; --N;
	vector<vector<int> > G(2 * N);
	for (int i = 0; i < N; ++i) {
		for (int j = 0; j < N; ++j) {
			int x;
			cin >> x;
			if (x == 1) {
				G[i].push_back(N + j);
				G[N + j].push_back(i);
			}
		}
	}
	vector<bool> vis, dec(2 * N, false);
	vector<int> match(2 * N, -1);
	function<bool(int)> find_augment = [&](int pos) {
		vis[pos] = true;
		for (int i : G[pos]) {
			if (!dec[i] && (match[i] == -1 || (!vis[match[i]] && find_augment(match[i])))) {
				match[i] = pos;
				match[pos] = i;
				return true;
			}
		}
		return false;
	};
	int cnt = 0;
	for (int i = 2 * N - 1; i >= N; --i) {
		vis = vector<bool>(2 * N, false);
		if (match[i] == -1 && find_augment(i)) {
			++cnt;
		}
	}
	if (cnt == N) {
		for (int i = N; i < 2 * N; ++i) {
			match[match[i]] = -1;
			match[i] = -1;
			vis = vector<bool>(2 * N, false);
			find_augment(i);
			dec[match[i]] = true;
		}
		cout << "yes" << endl;
		for (int i = 0; i < N; ++i) {
			cout << match[N + i] + 1 << '\n';
		}
	}
	else {
		cout << "no" << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 3312
final_rank: 10

code_snippet: #include <iostream>
#include <vector>
using namespace std;

#define FOR(i,m,n) for(int i=(m);i<(n);++i)
#define REP(i,n) FOR(i,0,n)
/*-------------------------------------------------*/
struct BipartiteMatching {
  vector<int> match;

  BipartiteMatching(int n) : n(n), graph(n), match(n, -1), used(n, -1), alive(n, true) {}

  void add_edge(int u, int v) {
    graph[u].emplace_back(v);
    graph[v].emplace_back(u);
  }

  int solve() {
    int res = 0;
    REP(i, n) if (alive[i] && match[i] == -1) {
      ++timestamp;
      if (dfs(i)) ++res;
    }
    return res;
  }

  int push_back(int ver) {
    match[match[ver]] = -1;
    match[ver] = -1;
    ++timestamp;
    dfs(ver);
    return match[ver];
  }

  void fix(int ver) {
    alive[ver] = false;
    if (match[ver] != -1) alive[match[ver]] = false;
  }

  int enable(int ver) {
    if (alive[ver]) return 0;
    alive[ver] = true;
    ++timestamp;
    return (dfs(ver) ? 1 : 0);
  }

  int disable(int ver) {
    if (!alive[ver]) return 0;
    alive[ver] = false;
    if (match[ver] == -1) return 0;
    match[match[ver]] = -1;
    ++timestamp;
    int tmp = match[ver];
    match[ver] = -1;
    return (dfs(tmp) ? 0 : -1);
  }

private:
  int n, timestamp = -1;
  vector<vector<int> > graph;
  vector<int> used;
  vector<bool> alive;

  bool dfs(int ver) {
    used[ver] = timestamp;
    for (int e : graph[ver]) if (alive[e]) {
      int tmp = match[e];
      if (tmp == -1 || (used[tmp] < timestamp && dfs(tmp))) {
        match[ver] = e;
        match[e] = ver;
        return true;
      }
    }
    return false;
  }
};

int main() {
  cin.tie(0); ios::sync_with_stdio(false);
  // freopen("input.txt", "r", stdin);

  int n; cin >> n; --n;
  BipartiteMatching bm(n * 2);
  REP(i, n) REP(j, n) {
    int b; cin >> b;
    if (b == 1) bm.add_edge(j, n + i);
  }
  if (bm.solve() == n) {
    cout << "yes\n";
  } else {
    cout << "no\n";
    return 0;
  }
  REP(i, n) {
    cout << bm.push_back(i) - n + 1 << '\n';
    bm.fix(i);
  }
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3308
final_rank: 4

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 99999999999999999
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


#define NUM 1005

struct Edge{
	Edge(int arg_to,int arg_capacity,int arg_rev_index){
		to = arg_to;
		capacity = arg_capacity;
		rev_index = arg_rev_index;
	}
	int to,capacity,rev_index;
};

int N;
int V;
int rank_index[NUM],component_index[NUM],rev_component[NUM];
vector<Edge> G[NUM];
int dist[NUM];
int cheked_index[NUM];

void add_edge(int from,int to,int capacity){
	G[from].push_back(Edge(to,capacity,G[to].size()));
	G[to].push_back(Edge(from,0,G[from].size()-1));
}

void delete_edge(int from,int index){

	G[from][index].capacity = 0;
	int rev_from = G[from][index].to;

	int left = 0,right = G[rev_from].size()-1,mid = (left+right)/2;

	while(left <= right){

		if(G[rev_from][mid].to == from){

			G[rev_from][mid].capacity = 0;
			return;

		}else if(G[rev_from][mid].to > from){

			right = mid-1;

		}else{
			left = mid+1;
		}
		mid = (left+right)/2;
	}
}

void bfs(int source){
	for(int i = 0; i < V; i++)dist[i] = -1;
	queue<int> Q;
	dist[source] = 0;
	Q.push(source);

	while(!Q.empty()){
		int node_id = Q.front();
		Q.pop();
		for(int i = 0; i < G[node_id].size(); i++){
			Edge &e = G[node_id][i];
			if(e.capacity > 0 && dist[e.to] < 0){
				dist[e.to] = dist[node_id]+1;
				Q.push(e.to);
			}
		}
	}
}

int dfs(int node_id,int sink,int flow){
	if(node_id == sink)return flow;

	for(int &i = cheked_index[node_id]; i < G[node_id].size(); i++){
		Edge &e = G[node_id][i];
		if(e.capacity > 0 && dist[node_id] < dist[e.to]){
			int tmp_flow = dfs(e.to,sink,min(flow,e.capacity));
			if(tmp_flow > 0){
				e.capacity -= tmp_flow;
				G[e.to][e.rev_index].capacity += tmp_flow;
				return tmp_flow;
			}
		}
	}
	return 0;
}


int max_flow(int source,int sink){
	int flow = 0,add;
	while(true){
		bfs(source);
		if(dist[sink] < 0)break;
		for(int i = 0; i < V; i++)cheked_index[i] = 0;
		while((add = dfs(source,sink,BIG_NUM)) > 0){
			flow += add;
		}
	}
	return flow;
}

bool find_a_path(int source,int sink){

	bfs(source);

	if(dist[sink] < 0){
		return false;
	}

	for(int i = 0; i < V; i++)cheked_index[i] = 0;

	return dfs(source,sink,1) == 1;
}

int main(){

	scanf("%d",&N);

	int source = 0,sink = 1;
	int index = 2;

	for(int i = 0; i <= N-2; i++){

		rank_index[i] = index++;
		add_edge(source,rank_index[i],1);
	}

	for(int i = 0; i <= N-2; i++){

		component_index[i] = index++;
		rev_component[component_index[i]] = i;
		add_edge(component_index[i],sink,1);
	}

	V = index;

	int tmp;

	for(int i = 0; i <= N-2; i++){
		for(int k = 0; k <= N-2; k++){

			scanf("%d",&tmp);
			if(tmp == 1){
				add_edge(rank_index[k],component_index[i],1);
			}
		}
	}

	if(max_flow(source,sink) < N-1){

		printf("no\n");
		return 0;
	}

	printf("yes\n");

	for(int rank = rank_index[0]; rank <= rank_index[N-2]; rank++){

		for(int i = G[rank].size()-1; i >= 0; i--){

			if(G[rank][i].capacity == 1){

				delete_edge(rank,i);

			}else{

				if(find_a_path(rank,G[rank][i].to)){

					delete_edge(rank,i);

				}else{

					printf("%d\n",rev_component[G[rank][i].to]+1);
					break;
				}
			}
		}
	}

	return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 3388
final_rank: 9

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 99999999999999999
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


#define NUM 1005

struct Edge{
	Edge(int arg_to,int arg_capacity,int arg_rev_index){
		to = arg_to;
		capacity = arg_capacity;
		rev_index = arg_rev_index;
	}
	int to,capacity,rev_index;
};

int N;
int V;
int rank_index[NUM],component_index[NUM],rev_component[NUM];
vector<Edge> G[NUM];
int dist[NUM];
int cheked_index[NUM];

void add_edge(int from,int to,int capacity){
	G[from].push_back(Edge(to,capacity,G[to].size()));
	G[to].push_back(Edge(from,0,G[from].size()-1));
}

void delete_edge(int from,int index){

	//ノーマル辺を消す
	G[from][index].capacity = 0;
	int rev_from = G[from][index].to;

	//逆辺を消す
	int left = 0,right = G[rev_from].size()-1,mid = (left+right)/2;

	while(left <= right){

		if(G[rev_from][mid].to == from){

			G[rev_from][mid].capacity = 0;
			return;

		}else if(G[rev_from][mid].to > from){

			right = mid-1;

		}else{
			left = mid+1;
		}
		mid = (left+right)/2;
	}
}

//sourceからの最短距離をBFSで計算する
void bfs(int source){
	for(int i = 0; i < V; i++)dist[i] = -1;
	queue<int> Q;
	dist[source] = 0;
	Q.push(source);

	while(!Q.empty()){
		int node_id = Q.front();
		Q.pop();
		for(int i = 0; i < G[node_id].size(); i++){
			Edge &e = G[node_id][i];
			if(e.capacity > 0 && dist[e.to] < 0){ //辺の容量が正で、かつエッジの行先に未訪問の場合
				dist[e.to] = dist[node_id]+1;
				Q.push(e.to);
			}
		}
	}
}

//増加パスをDFSで探す
int dfs(int node_id,int sink,int flow){
	if(node_id == sink)return flow; //終点についたらflowをreturn

	for(int &i = cheked_index[node_id]; i < G[node_id].size(); i++){ //node_idから出ているエッジを調査
		Edge &e = G[node_id][i];
		if(e.capacity > 0 && dist[node_id] < dist[e.to]){ //流せる余裕があり、かつsourceからの距離が増加する方法である場合
			int tmp_flow = dfs(e.to,sink,min(flow,e.capacity)); //流せるだけ流す
			if(tmp_flow > 0){ //流せた場合
				e.capacity -= tmp_flow; //流した分、エッジの容量を削減する
				G[e.to][e.rev_index].capacity += tmp_flow; //逆辺の容量を、流した分だけ増加させる
				return tmp_flow;
			}
		}
	}
	return 0;
}


//sourceからsinkへの最大流を求める
int max_flow(int source,int sink){ //source:始点 sink:終点
	int flow = 0,add;
	while(true){ //増加パスが存在する限り、流量を追加し続ける
		bfs(source);
		if(dist[sink] < 0)break; //sourceからsinkへと辿り着く残余グラフがない、つまり増加パスが無くなった場合、break
		for(int i = 0; i < V; i++)cheked_index[i] = 0;
		while((add = dfs(source,sink,BIG_NUM)) > 0){ //増加パスが見つかる間、加算
			flow += add;
		}
	}
	return flow;
}

bool find_a_path(int source,int sink){ //sourceからsinkへの増加パスがあるか調べる

	bfs(source);

	if(dist[sink] < 0){
		return false;
	}

	for(int i = 0; i < V; i++)cheked_index[i] = 0;

	return dfs(source,sink,1) == 1;
}

int main(){

	scanf("%d",&N);

	int source = 0,sink = 1;
	int index = 2;

	//上からの順番ノードのインデックス
	for(int i = 0; i <= N-2; i++){
		//★0オリジンにおいて(N-2)→(N-1)が最後の移動なので、iはN-2までで良い
		rank_index[i] = index++;
		add_edge(source,rank_index[i],1); //sourceから
	}

	//2部マッチング用の、部品ノードのインデックス
	for(int i = 0; i <= N-2; i++){

		component_index[i] = index++;
		rev_component[component_index[i]] = i; //逆引き表
		add_edge(component_index[i],sink,1);
	}

	V = index;

	int tmp;

	for(int i = 0; i <= N-2; i++){ //部品のループ
		for(int k = 0; k <= N-2; k++){ //棒のループ

			scanf("%d",&tmp);
			if(tmp == 1){ //位置kから、k+1に移動できるなら、順番ノードと部品を紐づける
				add_edge(rank_index[k],component_index[i],1);
			}
		}
	}

	if(max_flow(source,sink) < N-1){ //そもそも0→N-1に移動できないなら不可

		printf("no\n");
		return 0;
	}

	printf("yes\n");

	for(int rank = rank_index[0]; rank <= rank_index[N-2]; rank++){
	//for(int rank = rank_index[0]; rank <= rank_index[0]; rank++){
		//番号の大きい部品から、降順に見ていく
		for(int i = G[rank].size()-1; i >= 0; i--){

			if(G[rank][i].capacity == 1){ //エッジに流れていない場合

				delete_edge(rank,i); //流れないように、辺を論理削除

			}else{ //エッジに流れている場合

				//★残余グラフ上で別の経路がないか試す★
				if(find_a_path(rank,G[rank][i].to)){

					/*
					 * ★source→rank,
					 * G[rank][i].to→sinkの状況は変わらずに、
					 * rank→G[rank][i].toの経路が変わっただけなので、
					 * エッジiを論理削除すれば流量は変わらない
					 *
					 * */
					delete_edge(rank,i); //より小さい番号の部品とマッチできるので、辺を論理削除

				}else{ //流せない:辺確定

					printf("%d\n",rev_component[G[rank][i].to]+1);
					break;
				}
			}
		}
	}

	return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 3492
final_rank: 11

code_snippet: #include <stdio.h>
#include <bitset>
#include <vector>
using namespace std;
#define PB push_back
const int N=5e2+10;
vector<int> back[N],graph[N];
bitset<N> went,used;
int con[N],to[N];
bool dfs(int now){
    went[now]=true;
    for(int i:graph[now])if(con[i]==-1||(!used[con[i]]&&!went[con[i]]&&dfs(con[i]))){
        con[i]=now;
        to[now]=i;
        return true;
    }
    return false;
}
int main(){
    int n,temp;
    scanf("%d",&n);
    for(int i=1;i<n;i++){
        con[i]=-1;
        for(int j=1;j<n;j++){
            scanf("%d",&temp);
            if(temp==1){
                graph[i].PB(j);
                back[j].PB(i);
            }
        }
    }
    for(int i=1;i<n;i++){
        went.reset();
        if(!dfs(i)){
            printf("no\n");
            return 0;
        }
    }
    used.reset();
    printf("yes\n");
    for(int i=1;i<n;i++){
        for(int j:back[i])if(!used[j]){
            if(j>=con[i])break;
            went.reset();
            went[j]=true;
            temp=con[i];
            con[i]=j;
            con[to[j]]=-1;
            if(dfs(temp))break;
            con[i]=temp;
            con[to[j]]=j;
        }
        used[con[i]]=true;
        printf("%d\n",con[i]);
    }
}
accuracy: 1
time_ms: 20
memory_kb: 2920
final_rank: 1

code_snippet: #include <cstdio>
#include <iostream>
#include <algorithm>
#include <string>
#include <cstring>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <cmath>
#include <iomanip>
#include <cassert>
#include <bitset>
using namespace std;

typedef pair<int, int> P;
#define rep(i, n) for (int i=0; i<(n); i++)
#define all(c) (c).begin(), (c).end()
#define uniq(c) c.erase(unique(all(c)), (c).end())
#define index(xs, x) (int)(lower_bound(all(xs), x) - xs.begin())
#define _1 first
#define _2 second
#define pb push_back
#define INF 1145141919
#define MOD 1000000007

struct Bipartite_Matching {
  vector< vector< int > > G;
  vector< int > match, alive, used;
  int timestamp;

  Bipartite_Matching(int n) {
    timestamp = 0;
    G.resize(n);
    alive.assign(n, 1);
    used.assign(n, 0);
    match.assign(n, -1);
  }

  void add_edge(int u, int v) {
    G[u].push_back(v);
    G[v].push_back(u);
  }

  bool dfs(int v) {
    used[v] = timestamp;
    for (int u : G[v]) {
      int w = match[u];
      if(alive[u] == 0) continue;
      if(w == -1 || (used[w] != timestamp && dfs(w))) {
        match[v] = u;
        match[u] = v;
        return true;
      }
    }
    return false;
  }

  int bipartite_matching() {
    int ret = 0;
    rep(i, G.size()) {
      if(alive[i] == 0) continue;
      if(match[i] == -1) {
        ++timestamp;
        ret += dfs(i);
      }
    }
    return ret;
  }
};

struct Lexicographically_Matching : Bipartite_Matching {
  Lexicographically_Matching(int n) : Bipartite_Matching(n) {}

  int back(int k) {
    match[match[k]] = -1;
    match[k] = -1;
    ++timestamp;
    dfs(k);
    return match[k];
  }

  void decide(int k) {
    alive[match[k]] = 0;
    alive[k] = 0;
  }
};


int N;
signed main() {
  ios::sync_with_stdio(false); cin.tie(0);
  cin >> N;
  Lexicographically_Matching bip((N-1)*2);
  rep(i, N-1) {
    rep(j, N-1) {
      int x;
      cin >> x;
      if (x) bip.add_edge(i, j+N-1);
    }
  }
  if (bip.bipartite_matching() < N-1) {
    cout << "no\n";
    return 0;
  }
  cout << "yes\n";
  rep(i, N-1) {
    bip.decide(bip.back(i+N-1));
    cout << bip.match[i+N-1]+1 << "\n";
  }
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3268
final_rank: 2

code_snippet: #include <iostream>
#include <cstdio>
#include <vector>
#define _USE_MATH_DEFINES
#include <math.h>
#include <cstring>
#include <numeric>
#include <algorithm>
#include <stdlib.h>
#include <functional>
#include <string>
#include <array>
#include <map>
#include <queue>
#include <limits.h>
#include <set>
#include <stack>
#include <random>
#include <complex>
#include <unordered_map>
#include <nmmintrin.h>
#include <chrono>
const double EPS = 1e-8;
#define Scan(a) int a;scanf("%d", &a);
#define ScanS(a) char a[500];scanf("%s", a);
#define rep(i,s,n) for(int i = (s); (n) > i; i++)
#define REP(i,n) rep(i,0,n)
#define RANGE(x,a,b) ((a) <= (x) && (x) <= (b))
#define DUPLE(a,b,c,d) (RANGE(a,c,d) || RANGE(b,c,d) || RANGE(c,a,b) || RANGE(d,a,b))
#define INCLU(a,b,c,d) (RANGE(a,c,d) && (b,c,d))
#define PW(x) ((x)*(x))
#define ALL(x) (x).begin(), (x).end()
#define MODU 1000000007
#define bitcheck(a,b)   ((a >> b) & 1LL)
#define bitset(a,b)      ( a |= (1LL << b))
#define bitunset(a,b)    (a &= ~(1LL << b))
#define MP(a,b) make_pair((a),(b))
#define Manh(a,b) (abs((a).first-(b).first) + abs((a).second - ((b).second))
#define pritnf printf
#define scnaf scanf
#define itn int
#ifdef _MSC_VER
#define __builtin_popcount _mm_popcnt_u32
#define __builtin_popcountll _mm_popcnt_u64
#endif
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
ll gcd(ll a, ll b) {
	if (b == 0) return a;
	return gcd(b, a%b);
}
template<typename A, size_t N, typename T>
void Fill(A(&array)[N], const T &val) {
	std::fill((T*)array, (T*)(array + N), val);
}

int gcd(int a, int b) {
	if (b == 0) return a;
	return gcd(b, a%b);
}
pii Dir[8] = {
	{ 0 ,1 },{ -1 ,0 },{ 1 ,0 },{ 0 ,-1 },
	{ 1 ,1 },{ 1 ,-1 },{ -1 ,1 },{ -1 ,-1 }
};


pii operator+(pii obj, pii obj2) {
	return MP(obj.first + obj2.first, obj.second + obj2.second);
}
pii operator-(pii obj, pii obj2) {
	return MP(obj.first - obj2.first, obj.second - obj2.second);
}
class Graph {
public:
	int vn;
	int sumcost = 0;
	vector<vector<pii>> g;

	Graph(int n) {
		vn = n;
		g.resize(n);
	}
	virtual void con(int a, int b, int w) = 0;
	int getWeight(int f, int t) {
		auto itr = lower_bound(ALL(g[f]), make_pair(t, INT_MIN));
		if (itr != g[f].end())
			return itr->second;
		return INT_MIN;
	}
	int Costsum() {
		return sumcost;
	}
	void scan(int edcount, bool oindexed, bool w) {
		REP(i, edcount) {
			int a, b, c = 1;
			scanf("%d %d", &a, &b);
			if (w)scanf("%d", &c);
			con(a - oindexed, b - oindexed, c);
		}
	}
};
class BiDGraph : public Graph {//??????
public:
	BiDGraph(int n) : Graph(n) {}

	void con(int a, int b, int w = 1) {
		g[a].push_back({ b,w });
		g[b].push_back({ a, w });
		sumcost++;
	}
};
class DGraph : public Graph {//??????
public:
	DGraph(int n) : Graph(n) {}
	void con(int a, int b, int w = 1) {
		g[a].push_back({ b,w });
		sumcost++;
	}
};


class RGraph {//????????°??????
	struct edge{
		int to, cap = 0, rev;
		bool isrev;
	};
public:
	int sumflow = 0;

	vector<vector<edge>> g;

	RGraph(DGraph dg) : g(dg.g.size()){
		REP(i, dg.g.size()) {
			for (auto itr : dg.g[i]) {
				g[i].push_back({ itr.first, itr.second, (int)g[itr.first].size(), 0});
				g[itr.first].push_back({ i, 0, (int)g[i].size() - 1, 1});
			}
		}
	}

	void flow(edge& eg, int rate) {
		eg.cap -= rate;
		g[eg.to][eg.rev].cap += rate;
	}

};

RGraph FordFurkerson(DGraph g, int st, int en) {
	
	RGraph rg(g);

	vector<bool> used(g.g.size());

	function<int(int, int, int)> dfs = [&](int c, int p, int Min) {
		if (c == en) return Min;
		if (used[c]) return -1;
		used[c] = true;

		for (auto& itr : rg.g[c]) {
			if (itr.cap > 0) {
				int ret = dfs(itr.to, c, min(Min, itr.cap));
				if (ret != -1) {
					rg.flow(itr, ret);
					return ret;
				}
			}
		}

		return -1;
	};

	while (int zo = dfs(st, -1, INT_MAX) != -1) {
		fill(ALL(used), 0);
		rg.sumflow += zo;
	}

	return rg;
}

vector<int> BiMaxmatching(DGraph g, int scount, bool lexi = 0) { // scount????????????????????´??§???g???????????????scount???
	
	g.g.push_back(vector<pii>());
	g.g.push_back(vector<pii>());

	REP(i, scount) {
		g.con(g.g.size() - 2, i);
	}
	rep(i, scount, g.g.size() - 2) {
		g.con(i, g.g.size() - 1);
	}

	RGraph rg(FordFurkerson(g, g.g.size() - 2, g.g.size() - 1));

	vector<int> ans(scount, -1);

	if (lexi) {
		vector<bool> used(g.g.size()), alive(g.g.size(), 1);

		function<int(int, int, int)> dfs = [&](int c, int p, int Min) {
			if (c == g.g.size() - 1) return Min;
			if (used[c]) return -1;
			if (!alive[c]) return -1;
			used[c] = true;

			for (auto& itr : rg.g[c]) {
				if (itr.cap > 0) {
					int ret = dfs(itr.to, c, min(Min, itr.cap));
					if (ret != -1) {
						rg.flow(itr, ret);
						return ret;
					}
				}
			}

			return -1;
		};

		REP(i, scount) {
			rg.flow(rg.g[g.g.size() - 2][i], -1);
			for (auto& itr : rg.g[i]) {
				if (!itr.isrev && !itr.cap) {
					rg.flow(itr, -1);
					for (auto& itr2 : rg.g[itr.to]) {
						if (itr2.to == g.g.size() - 1)
							rg.flow(itr2, -1);
					}
				}
			}

			dfs(g.g.size() - 2, -1, INT_MAX);

			alive[i] = 0;
			for (auto itr : rg.g[i]) {
				if (!itr.isrev && !itr.cap) {
					alive[itr.to] = 0;
					ans[i] = itr.to;
				}
			}

			fill(ALL(used), 0);
		}

	}
	else {
		REP(i, scount) {
			for (auto itr : rg.g[i]) {
				if (!itr.isrev && !itr.cap) {
					ans[i] = itr.to;
				}
			}
		}
	}
	return ans;
}

int main() {
	int n;

	cin >> n;

	DGraph g(n * 2 - 2);

	REP(i, n - 1) {
		REP(j, n - 1) {
			int a;
			scanf("%d", &a);
			if (a)
				g.con(j, i + n - 1);
		}
	}


	vector<int> ans(BiMaxmatching(g, n-1,true));
	
	for(auto itr : ans)
		if (itr == -1) {
			cout << "no" << endl;
			return 0;
		}

	cout << "yes" << endl;
	for (auto itr : ans)
		printf("%d\n", itr - n + 2);

	return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 3884
final_rank: 13

code_snippet: #include "bits/stdc++.h"
using namespace std;
#ifdef _DEBUG
#include "dump.hpp"
#else
#define dump(...)
#endif

//#define int long long
#define rep(i,a,b) for(int i=(a);i<(b);i++)
#define rrep(i,a,b) for(int i=(b)-1;i>=(a);i--)
#define all(c) begin(c),end(c)
const int INF = sizeof(int) == sizeof(long long) ? 0x3f3f3f3f3f3f3f3fLL : 0x3f3f3f3f;
const int MOD = (int)(1e9) + 7;
template<class T> bool chmax(T &a, const T &b) { if (a < b) { a = b; return true; } return false; }
template<class T> bool chmin(T &a, const T &b) { if (b < a) { a = b; return true; } return false; }

struct HopcroftKarp {
	int n;
	vector<vector<int>> g;
	vector<int> match, dist;
	vector<bool> used, alive;
	HopcroftKarp(int n) : n(n), g(n), match(n), dist(n), used(n), alive(n, true) {}
	void addEdge(int u, int v) {
		g[u].emplace_back(v);
		g[v].emplace_back(u);
	}
	int maximumMatching() {
		int cnt = 0;
		fill(match.begin(), match.end(), -1);
		while (true) {
			buildAlternatingLevelGraph();
			fill(used.begin(), used.end(), false);
			int flow = 0;
			for (int u = 0; u < n; u++) {
				if (!alive[u])continue;
				if (match[u] == -1 && augment(u))
					flow++;
			}
			if (flow == 0)break;
			cnt += flow;
		}
		return cnt;
	}
	void buildAlternatingLevelGraph() {
		fill(dist.begin(), dist.end(), -1);
		queue<int> q;
		for (int u = 0; u < n; u++)
			if (match[u] == -1) {
				q.emplace(u);
				dist[u] = 0;
			}
		while (q.size()) {
			int u = q.front(); q.pop();
			for (int v : g[u]) {
				int w = match[v];
				if (w != -1 && dist[w] == -1) {
					dist[w] = dist[u] + 1;
					q.emplace(w);
				}
			}
		}
	};
	bool augment(int u) {
		used[u] = true;
		for (int v : g[u]) {
			if (!alive[v])continue;
			int w = match[v];
			if (w == -1 || (!used[w] && dist[w] == dist[u] + 1 && augment(w))) {
				match[u] = v;
				match[v] = u;
				used[v] = true;
				return true;
			}
		}
		return false;
	}
};


struct LexicographicallyBipartiteMatching :HopcroftKarp {
	LexicographicallyBipartiteMatching(int n) :HopcroftKarp(n) {}
	int maximumMatching() {
		for (int v = 0; v < n; v++)
			sort(g[v].begin(), g[v].end());
		int cnt = HopcroftKarp::maximumMatching();
		for (int v = 0; v < n; v++) {
			if (!alive[v] || match[v] == -1)continue;
			match[match[v]] = -1;
			match[v] = -1;
			fill(used.begin(), used.end(), false);
			augment(v);
			alive[match[v]] = 0;
			alive[v] = 0;
		}
		return cnt;
	}
	bool augment(int u) {
		used[u] = true;
		for (int v : g[u]) {
			if (!alive[v])continue;
			int w = match[v];
			if (w == -1 || (!used[w] && augment(w))) {
				match[u] = v;
				match[v] = u;
				return true;
			}
		}
		return false;
	}
};

signed main() {
	cin.tie(0);
	ios::sync_with_stdio(false);
	int N; cin >> N; N--;
	vector<vector<int>> b(N, vector<int>(N));
	rep(v, 0, N) rep(u, 0, N) { cin >> b[v][u]; }

	LexicographicallyBipartiteMatching lbm(N + N);
	rep(v, 0, N)rep(u, 0, N) {
		if (b[v][u])
			lbm.addEdge(u, N + v);
	}
	int res = lbm.maximumMatching();
	dump(res);
	if (res == N) {
		cout << "yes" << endl;
		rep(v, 0, N) {
			cout << lbm.match[v] - N + 1 << endl;
		}
	}
	else {
		cout << "no" << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 4128
final_rank: 14

code_snippet: #include "bits/stdc++.h"
using namespace std;
#ifdef _DEBUG
#include "dump.hpp"
#else
#define dump(...)
#endif

//#define int long long
#define rep(v,a,b) for(int v=(a);v<(b);v++)
#define rrep(v,a,b) for(int v=(b)-1;v>=(a);v--)
#define all(c) begin(c),end(c)
const int INF = sizeof(int) == sizeof(long long) ? 0x3f3f3f3f3f3f3f3fLL : 0x3f3f3f3f;
const int MOD = (int)(1e9) + 7;
template<class T> bool chmax(T &a, const T &b) { if (a < b) { a = b; return true; } return false; }
template<class T> bool chmin(T &a, const T &b) { if (b < a) { a = b; return true; } return false; }

struct BipartiteMatching {
	int n;
	vector<vector<int>> g;
	vector<int> match;
	vector<bool> used, alive;
	BipartiteMatching(int n) : n(n), g(n), match(n), used(n), alive(n, true) {}
	void addEdge(int u, int v) {
		g[u].emplace_back(v);
		g[v].emplace_back(u);
	}
	int maximumMatching() {
		int cnt = 0;
		fill(match.begin(), match.end(), -1);
		for (int v = 0; v < n; v++) {
			if (!alive[v])continue;
			if (match[v] == -1) {
				fill(used.begin(), used.end(), false);
				if (augment(v))cnt++;
			}
		}
		return cnt;
	}
	bool augment(int v) {
		used[v] = true;
		for (int u : g[v]) {
			if (!alive[u])continue;
			int w = match[u];
			if (w == -1 || (!used[w] && augment(w))) {
				match[v] = u;
				match[u] = v;
				return true;
			}
		}
		return false;
	}
};

struct LexicographicallyBipartiteMatching :BipartiteMatching {
	LexicographicallyBipartiteMatching(int n) :BipartiteMatching(n) {}
	int maximumMatching() {
		for (int v = 0; v < n; v++)
			sort(g[v].begin(), g[v].end());
		int cnt = BipartiteMatching::maximumMatching();
		for (int v = 0; v < n; v++) {
			if (!alive[v] || match[v] == -1)continue;
			match[match[v]] = -1;
			match[v] = -1;
			fill(used.begin(), used.end(), false);
			augment(v);
			alive[match[v]] = 0;
			alive[v] = 0;
		}
		return cnt;
	}
};

signed main() {
	cin.tie(0);
	ios::sync_with_stdio(false);
	int N; cin >> N; N--;
	vector<vector<int>> b(N, vector<int>(N));
	rep(v, 0, N) rep(u, 0, N) { cin >> b[v][u]; }

	LexicographicallyBipartiteMatching lbm(N + N);
	rep(v, 0, N)rep(u, 0, N) {
		if (b[v][u])
			lbm.addEdge(u, N + v);
	}
	int res = lbm.maximumMatching();
	dump(res);
	if (res == N) {
		cout << "yes" << endl;
		rep(v, 0, N) {
			cout << lbm.match[v] - N + 1 << endl;
		}
	}
	else {
		cout << "no" << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 4144
final_rank: 15

code_snippet: #include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cassert>
using namespace std;

#define INF (1<<30)
#define MAX 1000
 
class Edge{
public:
  int to, rev, cap, flow;
  Edge(int to=0, int rev=0, int cap=0, int flow=0):to(to), rev(rev), cap(cap), flow(flow){}
};
 
int V;
vector<Edge> G[MAX];

int N;
int P[MAX][MAX];
 
void connect( int source, int target, int cap ){
  G[source].push_back(Edge(target, G[target].size(), cap, 0));
  G[target].push_back(Edge(source, G[source].size()-1, 0, 0));
}
 
bool bfs(pair<int, int> pi[], int source, int target ){
  bool visited[MAX];
  queue<int> Q;
   
  for ( int i = 0; i < V; i++ ) {
    visited[i] = false;
    pi[i] = make_pair(-1, -1);
  }
   
  int u, v;
  Q.push( source );
  visited[source] = true;
   
  while( !Q.empty() ){
    u = Q.front(); Q.pop();
    if ( u == target ) return true;
    for( int i = 0; i < G[u].size(); i++ ){
      int v = G[u][i].to;
      if ( visited[v] ) continue;
      if ( G[u][i].cap > G[u][i].flow ){
	pi[v] = make_pair(u, i);
	visited[v] = true;
	Q.push(v);
      }
    }
  }
  return false;
}
 
int edmonds_karp(int source, int target ){
  int flow;
  pair<int, int> pi[MAX]; //pre, to index
 
  while ( bfs(pi, source, target ) ){
    flow = INF;
    for ( int v = target; v != source; v = pi[v].first ){
      int u = pi[v].first;
      int idx = pi[v].second;
      flow = min(flow, G[u][idx].cap - G[u][idx].flow);
    }
    for ( int v = target; v != source; v = pi[v].first ){
      int u = pi[v].first;
      int idx = pi[v].second;
      int rev = G[u][idx].rev;
      G[u][idx].flow += flow;
      G[v][rev].flow = -G[u][idx].flow;
    }
  }
 
  flow = 0;
  for ( int i = 0; i < G[source].size(); i++ )  flow += G[source][i].flow;
   
  return flow;
}


void solve(){
  for ( int i = 0; i < V; i++ ) G[i].clear();

  for ( int i = 0; i < N; i++ ){
    connect(0, i+1, 1);
  }
  for ( int i = 0; i < N; i++ ){
    for ( int j = 0; j < N; j++ ){
      if ( P[j][i] == 1 ){
	connect(i+1, N+1+j, P[j][i]);
      }
    }
  }
  for ( int i = 0; i < N; i++ ){
    connect(N+1+i, V-1, 1);
  }

  int f = edmonds_karp(0, V - 1);
  if ( f != N ){
    cout << "no" << endl; return;
  }
  cout << "yes" << endl;

  pair<int, int> pi[MAX]; //pre, to index

  for ( int i = 1; i <= N; i++ ){
    //for ( int j = N-1; j >= 0; j-- ){
    for ( int j = G[i].size()-1; j >= 1; j-- ){ // j = 0, rev of i
      //      int s = i+1;
      //      int t = j+N+1;
      int s = i;
      int t = G[i][j].to;
      if ( G[s][j].flow == 0 ) {
	G[s][j].cap = 0;
	// not use
      } else {
	assert(G[s][j].flow == 1 );
	G[s][j].cap = 0;
	G[s][j].flow = 0;
	G[G[s][j].to][G[s][j].rev] = 0;
	if ( bfs(pi, s, t) ){
	  int flow = 1;
	  for ( int v = t; v != s; v = pi[v].first ){
	    int u = pi[v].first;
	    int idx = pi[v].second;
	    int rev = G[u][idx].rev;
	    G[u][idx].flow += flow;
	    G[v][rev].flow = -G[u][idx].flow;
	  }
	  // not use
	} else {
	  G[s][j].cap = 1;
	  G[s][j].flow = 1;
	  G[G[s][j].to][G[s][j].rev] = -1;
	  cout << t-N << endl;
	  // use
	}
      }
    }
  }
}

int main(){
  //  cin >> N;
  scanf("%d", &N);
  N--;
  V = 2*N + 2;
  for ( int i = 0; i < N; i++ ){
    for ( int j = 0; j < N; j++ ){
      //      cin >> P[i][j];      
      scanf("%d", &P[i][j]);

    }
  }
  solve();
}
accuracy: 1
time_ms: 30
memory_kb: 5492
final_rank: 17

code_snippet: #include "bits/stdc++.h"
using namespace std;


#define REP(i,n) for(int i=0;i<(int)n;++i)
#define FOR(i,c) for(auto i=(c).begin();i!=(c).end();++i)
#define ALL(c) (c).begin(), (c).end()



typedef vector<int> Weight;
typedef int Cap;
const Weight W_INF = vector<int>(1000,100000000);
const Weight W_ZERO = vector<int>(1000, 0);
const Cap C_INF= INT_MAX;
const Cap C_ZERO = 0;

struct Edge {
	int src, dst;
	Cap capacity;
	Weight cost;
	Edge(int src, int dst, const Cap& acap, const Weight& acost) :
		src(src), dst(dst), capacity(acap), cost(acost) {
	}
};
Weight operator-(const Weight&w) {
	Weight aw(w);
	for (auto&a : aw) {
		a = -a;
	}
	return aw;
}
Weight operator+(const Weight&l, const Weight&r) {
	Weight aw(l);
	for (int i = 0; i < aw.size(); ++i) {
		aw[i] += r[i];
	}
	return aw;
}
Weight operator-(const Weight&l, const Weight&r) {
	return l + (-r);
}
Weight operator*(const Weight&w, const Cap&c) {
	Weight aw(w);
	for (int i = 0; i < aw.size(); ++i) {
		aw[i] *= c;
	}
	return aw;
}
Weight operator*( const Cap&c,const Weight&w) {
	Weight aw(w);
	for (int i = 0; i < aw.size(); ++i) {
		aw[i] *= c;
	}
	return aw;
}
bool operator <(const Weight&l, const Weight&r) {
	assert(l.size() == r.size());
	for (int i = 0; i < l.size(); ++i) {
		if (l[i] < r[i])return true;
		else if (l[i] == r[i])continue;
		else return false;
	}
	return false;
}
bool operator < (const Edge &e, const Edge &f) {
	return e.cost > f.cost;
}
typedef vector<Edge> Edges;
typedef vector<Edges> Graph;


#define RESIDUE(s,t) (capacity[s][t]-flow[s][t])
#define RCOST(u,v) (cost[u][v] + h[u] - h[v])

//??°?????????????????§???????????????????????¨?????????

//Graph &ag
//????????§???????????????(u, v, capacity, cost) ??????????????????(u, v, 0, -cost) ???????????°????????????????????¶?????????????????§????´???°????????§???????????°???????????????
//int s, int t
//?????????????§??????¨?????????
//?????????
//?????¨??¨????????????????????????
pair<Weight, Cap> minimumCostFlow(const Graph &ag, int s, int t) {
//check???????´???°??????????????£???????????????
	Graph g(ag);
	for (int i = 0; i < ag.size(); ++i) {
		for (int j = 0; j < ag[i].size(); ++j) {
			int d = ag[i][j].dst;
			int s = ag[i][j].src;

			bool ok = false;
			for (int k = 0; k < ag[d].size(); ++k) {
				if (ag[d][k].src == s) {
					ok = true;
					break;
				}
			}
			if (!ok) {
				g[d].push_back(Edge(d, s, C_ZERO, -ag[i][j].cost));
			}
		}
	}
	const int n = g.size();
	vector<vector<Cap>> capacity(n, vector<Cap>(n)), flow(n, vector<Cap>(n));
	vector<vector<Weight>>cost(n, vector<Weight>(n,W_ZERO));
	for (int u = 0; u < n;++u){
		for (auto e : g[u]) {
			capacity[e.src][e.dst] = capacity[e.src][e.dst] + e.capacity;
			cost[e.src][e.dst] = cost[e.src][e.dst] + e.cost;
		}
	}
	pair<Weight, Cap> total(W_ZERO,C_ZERO); // (cost, flow)
	vector<Weight> h(n,W_ZERO);

	for (Cap F = C_INF; F > 0; ) { // residual flow
		vector<Weight> d(n, W_INF); d[s] = W_ZERO;
		vector<int> p(n, -1);
		priority_queue<Edge> Q; // "e < f" <=> "e.cost > f.cost"
		for (Q.push(Edge(-2, s, C_ZERO, W_ZERO)); !Q.empty(); ) {
			Edge e = Q.top(); Q.pop();
			if (p[e.dst] != -1) continue;
			p[e.dst] = e.src;
			for (auto f : g[e.dst]) {

			
				if (RESIDUE(f.src, f.dst) > 0) {
					if (d[f.dst] > d[f.src] + RCOST(f.src, f.dst)) {
						d[f.dst] = d[f.src] + RCOST(f.src, f.dst);
						Q.push(Edge(f.src, f.dst, 0, d[f.dst]));
					}
				}
			}
		}
		if (p[t] == -1) break;

		Cap f = F;
		for (int u = t; u != s; u = p[u]) {
			f = min(f, RESIDUE(p[u], u));
		}
		for (int u = t; u != s; u = p[u]) {
			total.first =total.first+ f * cost[p[u]][u];
			flow[p[u]][u] =flow[p[u]][u]+ f; flow[u][p[u]] =flow[u][p[u]]- f;
		}
		F = F - f;
		total.second =total.second+ f;
		for (int u = 0; u < n; ++u) {
			h[u] =h[u] + d[u];
		}
	}
	return total;
}
int main() {
	int N; cin >> N;
	const int start = 0;
	const int from = 1;
	const int to = from + N;
	const int goal=to + N;
	Graph g(goal + 1);
	for (int i = 0; i < N - 1; ++i) {
		g[0].push_back(Edge(0, from + i, 1, W_ZERO));
	}
	for (int i = 0; i < N - 1; ++i) {
		for (int j = 0; j < N - 1; ++j) {
			int a; cin >> a;
			if (a) {

				vector<int>v(1000);
				v[i] = j;
				g[from + i].push_back(Edge(from + i, to + j, 1, v));
			}
		}
	}
	for (int i = 0; i < N - 1; ++i) {
		g[to + i].push_back(Edge(to + i, goal, 1, W_ZERO));
	}
	auto p = minimumCostFlow(g, start, goal);
	if (p.second == N - 1) {
		cout << "yes" << endl;
		vector<int>ans(N - 1);
		for (int j = 0; j < N - 1; ++j) {
			ans[p.first[j]] = j;
		}
		for (int j = 0; j < N - 1; ++j) {
			cout << 1+ans[j] << endl;
		}
	}
	else {
		assert(p.second < N - 1);
		cout << "no" << endl;
	}
	return 0;
}
accuracy: 0.16666666666666666
time_ms: 30
memory_kb: 16676
final_rank: 20