Problem:
Problem I:
Aaron と Bruce
Aaron は凶悪な犯罪者である．
    彼は幾度も犯罪を繰り返しながら
    （万引き2回，のぞき16回，下着泥棒256回，食い逃げ65,536回）
    も，その人並み外れた身体能力を用いて
    警察の手から逃れ続けてきた．
    Bruce は警察官である．
    彼は突出した運動能力は持っていないが，
    写真撮影が趣味であり，
    彼の撮った写真が雑誌に載るほどの腕前を持っている．
ある日，Bruce は山奥に写真撮影をしに来た．
    すると偶然 Aaron のアジトを突き止めてしまった．
    Bruce が逃げる Aaron を追っていくと，
    彼らは落とし穴に落ちて古代遺跡の中に迷い込んでしまった．
古代遺跡の中はいくつかの部屋と，部屋どうしを結ぶ通路で構成されている．
    古代遺跡に
M
個の部屋があるとき，
    遺跡内の部屋にはそれぞれ 0 から
M
−1 までの番号がつけられている．
Aaron は逃げている間に時効を迎えるかもしれないと考えたので，
    Bruce が最適に移動したときに一番長い間逃げ続けられるように
    遺跡の中を移動する．
    Bruce は早く Aaron を写真に収めたいので，
    Aaron が最適に移動したときに一番早く Bruce を写真に収められるように
    遺跡の中を移動する．
Aaron と Bruce は順番に行動する．
    最初は Aaron の番とする．
    それぞれの順番のとき，隣接している部屋のどれか1つに移動，
    もしくはその場にとどまることができる．
    Aaron と Bruce が同じ部屋に入ったとき，
    Bruce は Aaron を撮影するものとする．
Bruce が Aaron を撮影するのにどれくらいの時間がかかるかを求めて欲しい．
    時間はターン数で表すこととし，
    Aaron と Bruce がともに1回行動し終わったら1ターンと数える．
例えば，図5のような状況のとき，
    Aaron は部屋5に逃げ込めば Bruce は4ターンでたどり着くが，
    Aaron が部屋7に逃げ込めば Bruce はたどり着くのに5ターンかかる．
    Aaron にとっては部屋7に逃げ込むことで一番長く逃げ続けられるので
    答えは5ターンとなる．
図5: Aaron が5ターン逃げ続けられる例．
また，図6のような状況のとき，
    Aaron が Bruce から遠ざかるように部屋を移動することで
    いつまでも逃げ回ることができる．
図6: Aaron がいつまでも逃げ続けられる例．
Input
入力の最初の行にデータセット数を表す数
N
(0 <
N
≤ 100) が与えられる．
    次の行から
N
個のデータセットが続く．
各データセットは古代遺跡の形状と Aaron と Bruce の初期位置からなる．
    初めに，古代遺跡の部屋の数
M
(2 ≤
M
≤ 50) が与えられる．
    次に要素数
M
×
M
の行列が与えられる．
    各行列の要素は 0 もしくは 1 であり，
i
行目の
j
番目の数字が 1 ならば，
    部屋
i
と部屋
j
は通路でつながっているということを意味する
    （ただし，行列の行番号と列番号は0から数える）．
    行列の (
i
,
j
) 成分と
    (
j
,
i
) 成分の値は必ず等しく，
    (
i
,
i
) 成分の値は 0 である．
    続いて，2つの整数
a
,
b
が与えられる．
    各整数はそれぞれ Aaron の初期位置の部屋番号
    (0 ≤
a
<
M
) と
    Bruce の初期位置の部屋番号
    (0 ≤
b
<
M
) を示す．
a
と
b
の値は必ず異なる．
Output
各データセットごとに，Bruce が Aaron を撮影するのに何ターンかかるかを
    1行で出力せよ．
    どれだけたっても撮影できない場合は
    “
infinity
” と出力せよ．
Sample Input
6
8
0 1 0 0 0 0 0 0
1 0 1 0 0 0 0 0
0 1 0 1 1 0 0 0
0 0 1 0 0 0 0 0
0 0 1 0 0 1 1 0
0 0 0 0 1 0 0 0
0 0 0 0 1 0 0 1
0 0 0 0 0 0 1 0
3 0
4
0 1 1 0
1 0 0 1
1 0 0 1
0 1 1 0
1 0
5
0 1 0 1 0
1 0 0 1 0
0 0 0 0 1
1 1 0 0 0
0 0 1 0 0
2 0
5
0 1 0 0 1
1 0 1 1 1
0 1 0 1 0
0 1 1 0 1
1 1 0 1 0
2 4
5
0 1 0 1 0
1 0 1 1 0
0 1 0 0 1
1 1 0 0 1
0 0 1 1 0
3 0
5
0 1 0 1 1
1 0 1 0 1
0 1 0 1 0
1 0 1 0 1
1 1 0 1 0
0 4
Output for the Sample Input
5
infinity
infinity
2
infinity
1

Submitted solutions:

code_snippet: //#include <atcoder/all>
#include <bits/stdc++.h>
using namespace std;
using lint = long long;
constexpr lint mod = 1e9 + 7;
#define all(x) begin(x), end(x)
#define bitcount(n) __builtin_popcountll((lint)(n))
#define fcout cout << fixed << setprecision(15)
#define highest(x) (63 - __builtin_clzll(x))
#define rep(i, n) for(int i = 0; i < int(n); i++)
#define rep2(i, l, r) for(int i = int(l); i < int(r); i++)
#define repr(i, n) for(int i = int(n) - 1; i >= 0; i--)
#define repr2(i, l, r) for(int i = int(r) - 1; i >= int(l); i--)
constexpr int inf9 = 1e9; constexpr lint inf18 = 1e18;
inline void Yes(bool condition){ if(condition) cout << "Yes" << endl; else cout << "No" << endl; }
template<class itr> void array_output(itr start, itr goal){ for(auto i = start; i != goal; i++) cout << (i == start ? "" : " ") << (*i); cout << endl; }
template<class itr> void cins(itr first, itr last){ for(auto i = first; i != last; i++){ cin >> (*i); } }
template<class T> T gcd(T a, T b){ if(b) return gcd(b, a % b); else return a; }
template<class T> T lcm(T a, T b){ return a / gcd(a, b) * b; }
template<class T> bool chmax(T &a, const T &b){ if(a < b){ a = b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b){ if(b < a){ a = b; return 1; } return 0; }
inline int has(lint i, int j){ return (i >> j) & 1; }
int dy[4] = {1, 0, -1, 0}; int dx[4] = {0, 1, 0, -1};
bool is_inside(lint y, lint x, lint H, lint W){ return (0 <= y && y < H && 0 <= x && x < W); }

struct io_init {
    io_init() {
        cin.tie(nullptr); cout.tie(nullptr);
        std::ios::sync_with_stdio(false);
    }
} io_init;

int n;
int g[55][55];

const int border = 105;

int dp[55][55][2][110];

int move(int a, int b, bool is_aaron, int cnt){
    if(cnt == border){
        return cnt;
    }
    if(a == b){
        return cnt;
    }
    if(dp[a][b][is_aaron][cnt] != -1){
        return dp[a][b][is_aaron][cnt];
    }
    if(is_aaron){
        int ans = move(a, b, !is_aaron, cnt + 1);
        rep(i, n){
            if(g[a][i]){
                ans = max(ans, move(i, b, !is_aaron, cnt + 1));
            }
        }
        return dp[a][b][is_aaron][cnt] = ans;
    }else{
        int ans = move(a, b, !is_aaron, cnt + 1);
        rep(i, n){
            if(g[b][i]){
                ans = min(ans, move(a, i, !is_aaron, cnt + 1));
            }
        }
        return dp[a][b][is_aaron][cnt] = ans;
    }
}

void solve(){
    cin >> n;
    rep(i, n) rep(j, n){
        cin >> g[i][j];
    }
    int a, b;
    cin >> a >> b;
    
    memset(dp, -1, sizeof(dp));
    int ans = move(a, b, true, 0);
    if(ans == border) cout << "infinity" << endl;
    else cout << ans / 2 << endl;
}

int main(){
    int t;
    cin >> t;
    rep(i, t){
        solve();
    }
}
accuracy: 1
time_ms: 190
memory_kb: 5964
final_rank: 11

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


#define NUM 50
#define MAX_TURN 5005

enum Type{
	turn_A,
	turn_B,
};

int num_room;
int dp[2][MAX_TURN][NUM][NUM];
vector<int> G[NUM];

int recursive(Type type,int num_turn,int loc_A,int loc_B){

	if(dp[type][num_turn][loc_A][loc_B] != -1)return dp[type][num_turn][loc_A][loc_B];

	if(loc_A == loc_B){
		return dp[type][num_turn][loc_A][loc_B] = num_turn;
	}

	if(num_turn == num_room){
		return dp[type][num_turn][loc_A][loc_B] = BIG_NUM;
	}

	int ret;

	if(type == turn_A){

		int maximum = max(0,recursive(turn_B,num_turn,loc_A,loc_B));

		for(int i = 0; i < G[loc_A].size(); i++){
			maximum = max(maximum,recursive(turn_B,num_turn,G[loc_A][i],loc_B));
		}

		ret = maximum;

	}else{

		int minimum = min(BIG_NUM,recursive(turn_A,num_turn+1,loc_A,loc_B));

		for(int i = 0; i < G[loc_B].size(); i++){
			minimum = min(minimum,recursive(turn_A,num_turn+1,loc_A,G[loc_B][i]));
		}

		ret = minimum;
	}

	return dp[type][num_turn][loc_A][loc_B] = ret;
}

void func(){

	scanf("%d",&num_room);

	for(int i = 0; i < num_room; i++)G[i].clear();

	int tmp;

	for(int from = 0; from < num_room; from++){
		for(int to = 0; to < num_room; to++){
			scanf("%d",&tmp);
			if(tmp == 0)continue;
			G[from].push_back(to);
		}
	}

	for(int i = 0; i < MAX_TURN; i++){
		for(int a = 0; a < num_room; a++){
			for(int b = 0; b < num_room; b++){
				dp[turn_A][i][a][b] = -1;
				dp[turn_B][i][a][b] = -1;
			}
		}
	}

	int loc_A,loc_B;

	scanf("%d %d",&loc_A,&loc_B);

	int ans = recursive(turn_A,0,loc_A,loc_B);

	if(ans == BIG_NUM){
		printf("infinity\n");
	}else{
		printf("%d\n",ans);
	}
}

int main(){

	int num_case;

	scanf("%d",&num_case);

	for(int loop = 0; loop < num_case; loop++){
		func();
	}

	return 0;
}
accuracy: 1
time_ms: 520
memory_kb: 101008
final_rank: 20

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

vector< int > graph[50];
int N, M;
int dp[50][50][5100];
 
int getTern(int Aaron, int Bruth, bool which, int cost)
{
  int ret;
  if(Aaron == Bruth) {
    return(dp[Aaron][Bruth][cost] = cost);
  } else if(cost == M * 2) {
    return(dp[Aaron][Bruth][cost] = 1 << 30);
  } else if(~dp[Aaron][Bruth][cost]) {
    return(dp[Aaron][Bruth][cost]);
  } else if(which) {
    ret = 1 << 30;
    for(int i = 0; i < graph[Bruth].size(); i++) { 
      ret = min(ret, getTern(Aaron, graph[Bruth][i], false, cost + 1));
    }
    ret = min(ret, getTern(Aaron, Bruth, false, cost + 1));
  } else {
    ret = 0;
    for(int i = 0; i < graph[Aaron].size(); i++) {
      ret = max(ret, getTern(graph[Aaron][i], Bruth, true, cost + 1));
    }
    ret = max(ret, getTern(Aaron, Bruth, true, cost + 1));
  }
  return(dp[Aaron][Bruth][cost] = ret);
}

int main()
{
  cin >> N;
  while(N--) {
    fill_n(**dp, 50 * 50 * 5100, -1);
    cin >> M;
    for(int i = 0; i < M; i++) {
      graph[i].clear();
      for(int j = 0; j < M; j++) {
        bool line;
        cin >> line;
        if(line) graph[i].push_back(j);
      }
    }
    int A, B;
    cin >> A >> B;
    int dist = getTern(A, B, false, 0) / 2;
    if(dist >= 1 << 29) {
      puts("infinity");
    } else {
      cout << dist << endl;
    }
  }
}
accuracy: 1
time_ms: 530
memory_kb: 51040
final_rank: 18

code_snippet: #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<list>
#include<queue>
#include<deque>
#include<algorithm>
#include<numeric>
#include<utility>
#include<complex>
#include<functional>
 
using namespace std;

/* constant */

const int MAX_M = 50;
const int MAX_K = 300;
const int INF = 1 << 30;

/* typedef */

typedef vector<int> vi;

/* global variables */

int n, m;
vi nbrs[MAX_M];
int cache[MAX_M][MAX_M][MAX_K];

/* subroutines */

int rec(int k, int a, int b) {
  if (k >= MAX_K) return INF;
  if (a == b) return (cache[a][b][k] = k);
  if (cache[a][b][k] >= 0) return cache[a][b][k];

  int ans;
  
  // Aaron
  if (! (k & 1)) {
    ans = 0;
    vi& nbra = nbrs[a];
    for (vi::iterator vit = nbra.begin(); vit != nbra.end(); vit++) {
      int c = rec(k + 1, *vit, b);
      if (ans < c) ans = c;
    }
  }
  // Bruce
  else {
    ans = INF;
    vi& nbrb = nbrs[b];
    for (vi::iterator vit = nbrb.begin(); vit != nbrb.end(); vit++) {
      int c = rec(k + 1, a, *vit);
      if (ans > c) ans = c;
    }
  }

  return (cache[a][b][k] = ans);
}

/* main */

int main() {
  cin >> n;
  while (n--) {
    cin >> m;

    for (int i = 0; i < m; i++) {
      nbrs[i].clear();
      for (int j = 0; j < m; j++) {
	int on;
	cin >> on;
	if (on || i == j) nbrs[i].push_back(j);
      }
    }

    int ai, bi;
    cin >> ai >> bi;
    
    memset(cache, -1, sizeof(cache));

    int ans = rec(0, ai, bi);
    if (ans >= INF) cout << "infinity" << endl;
    else cout << (ans / 2) << endl;
  }

  return 0;
}
accuracy: 1
time_ms: 610
memory_kb: 4188
final_rank: 13

code_snippet: #include <sstream>
#include <string>
#include <vector>
#include <map>
#include <algorithm>
#include <iostream>
#include <utility>
#include <set>
#include <cctype>
#include <queue>
#include <stack>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <climits>
using namespace std;

typedef long long ll;
const int dx[] = {1, 0, -1, 0};
const int dy[] = {0, 1, 0, -1};

const int MAXM = 64;
vector<int> G[MAXM];
const int LIMIT = 500;
int dp[64][64][LIMIT];

int dfs(int a, int b, int t) {
    if (a == b) return t;
    if (t >= LIMIT) return LIMIT;
    if (dp[a][b][t] >= 0) return dp[a][b][t];
    if ((t & 1) == 0) {
        int ret = dfs(a, b, t+1);
        for (int i = 0; i < (int)G[a].size(); i++) {
            ret = max(ret, dfs(G[a][i], b, t+1));
        }
        return dp[a][b][t] = ret;
    } else {
        int ret = LIMIT;
        for (int i = 0; i < (int)G[b].size(); i++) {
            ret = min(ret, dfs(a, G[b][i], t+1));
        }
        return dp[a][b][t] = ret;
    }
}

int main(void) {
    int T;
    cin >> T;
    while (T--) {
        for (int i = 0; i < MAXM; i++) G[i].clear();
        for (int i = 0; i < 64; i++) for (int j = 0; j < 64; j++) {
            for (int k = 0; k < LIMIT; k++) {
                dp[i][j][k] = -1;
            }
        }
        int a, b;
        int M;
        cin >> M;
        for (int i = 0; i < M; i++) {
            for (int j = 0; j < M; j++) {
                int tmp;
                scanf("%d", &tmp);
                if (tmp == 1) G[i].push_back(j);
            }
        }
        scanf("%d %d", &a, &b);
        int ans = dfs(a, b, 0);
        if (ans >= LIMIT) cout << "infinity" << endl;
        else cout << ans/2 << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 1020
memory_kb: 9320
final_rank: 15

code_snippet: #include<bits/stdc++.h>
#define rep(i,n) for(int i=0;i<(int)(n);i++)
using namespace std;

const int INF = 1e8;
int n,m;
int b[55][55];
int memo[2][55][55];

int main(){
  cin >> n;
  while(n--){
    cin >> m;
    rep(i,m)rep(j,m)cin >> b[i][j];
    int s,t;
    cin >> s >> t;

    memset(memo,-1,sizeof(memo));
    rep(i,m)memo[0][i][i] = 0;

    for(;;){
      bool f = false;
      rep(i,m)rep(j,m){
	if(i==j)continue;
	int maxv = memo[1][i][j];
	rep(k,m){
	  if(b[k][i])maxv = max(maxv, memo[1][k][j]);
	}
	maxv++;
	if(maxv>m)maxv = INF;

	if(memo[0][i][j] != maxv){
	  if(memo[0][i][j] == INF)continue;
	  memo[0][i][j] = maxv;
	  f = true;
	}
      }

      rep(i,m)rep(j,m){
	if(i==j)continue;
	int minv = memo[0][i][j];
	rep(k,m){
	  if(b[j][k]){
	    if(memo[0][i][k]>=0 && (minv<0 || minv>memo[0][i][k])){
	      minv = memo[0][i][k];
	    }
	  }
	}
	if(minv>m)minv = INF;

	if(memo[1][i][j] != minv){
	  if(memo[1][i][j] == INF)continue;
	  memo[1][i][j] = minv;
	  f = true;
	}
      }

      if(!f)break;
    }

    if(memo[0][s][t] == INF)cout << "infinity" << endl;
    else cout << memo[0][s][t] << endl;      
  }
}
accuracy: 1
time_ms: 110
memory_kb: 1208
final_rank: 8

code_snippet: #include <iostream>
#include <sstream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <cstring>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <set>
#include <bitset>
#include <numeric>
#include <utility>
#include <iomanip>
#include <algorithm>
#include <functional>
using namespace std;

typedef long long ll;
typedef vector<int> vint;
typedef vector<long long> vll;
typedef pair<int,int> pint;
typedef pair<long long, long long> pll;

#define MP make_pair
#define PB push_back
#define ALL(s) (s).begin(),(s).end()
#define EACH(i, s) for (__typeof__((s).begin()) i = (s).begin(); i != (s).end(); ++i)
#define COUT(x) cout << #x << " = " << (x) << " (L" << __LINE__ << ")" << endl

template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }
template<class T1, class T2> ostream& operator << (ostream &s, pair<T1,T2> P) 
{ return s << '<' << P.first << ", " << P.second << '>'; }
template<class T> ostream& operator << (ostream &s, vector<T> P) 
{ for (int i = 0; i < P.size(); ++i) { if (i > 0) { s << " "; } s << P[i]; } return s; }
template<class T> ostream& operator << (ostream &s, vector<vector<T> > P) 
{ for (int i = 0; i < P.size(); ++i) { s << endl << P[i]; } return s << endl; }
template<class T1, class T2> ostream& operator << (ostream &s, map<T1,T2> P) 
{ EACH(it, P) { s << "<" << it->first << "->" << it->second << "> "; } return s; }



/*
今回は、常に、
a側: Win or Draw
b側: Lose or Draw
がわかっているので, Win or Loseの判定は要らない -> adp, bdpの初期化が-INF, INFでよい. 
*/

const int INF = 1<<29;
int CASE;
int n, sa, sb;
int G[55][55];

int adp[55][55];
int bdp[55][55];
bool aknown[55][55];
bool bknown[55][55];

int solve() {
    cin >> n;
    for (int i = 0; i < n; ++i) for (int j = 0; j < n; ++j) cin >> G[i][j];

    cin >> sa >> sb;
    for (int i = 0; i < 55; ++i) for (int j = 0; j < 55; ++j) adp[i][j] = -1, bdp[i][j] = -1;
    for (int i = 0; i < 55; ++i) adp[i][i] = 0;
    
    int LIM = n*n + 1;
    bool update = false;
    for (int ite = 0; ite <= LIM; ++ite) {
        update = false;
        
        // A's turn
        for (int i = 0; i < n; ++i) for (int j = 0; j < n; ++j) {
            int Max = -INF;
            bool unknown = false;
            for (int k = 0; k < n; ++k) {
                if (G[i][k] == 0 && i != k) continue;
                if (bdp[k][j] == -1) { unknown = true; continue; }
                chmax(Max, bdp[k][j] + 1);
            }
            if (Max > -INF && !unknown) {
                if (adp[i][j] == -1) { adp[i][j] = Max; update = true; }
                else if (chmax(adp[i][j], Max)) update = true;
            }
        }
        
        // B's tuen
        for (int i = 0; i < n; ++i) for (int j = 0; j < n; ++j) {
            int Min = INF;
            for (int k = 0; k < n; ++k) {
                if (G[j][k] == 0 && j != k) continue;
                if (adp[i][k] == -1) { continue; }
                chmin(Min, adp[i][k] + 1);
            }
            if (Min < INF) {
                if (bdp[i][j] == -1) { bdp[i][j] = Min; update = true; }
                else if (chmin(bdp[i][j], Min)) update = true;
            }
        }

        if (!update) break;
    }

    if (adp[sa][sb] == -1) return -1;
    else return adp[sa][sb]/2;
}

int main() {
    cin >> CASE;
    for (int AAA = 0; AAA < CASE; ++AAA) {
        int res = solve();
        if (res != -1) cout << res << endl;
        else puts("infinity");
    }
    return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 1200
final_rank: 6

code_snippet: #include <iostream>
#include <sstream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <cstring>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <set>
#include <bitset>
#include <numeric>
#include <utility>
#include <iomanip>
#include <algorithm>
#include <functional>
using namespace std;

typedef long long ll;
typedef vector<int> vint;
typedef vector<long long> vll;
typedef pair<int,int> pint;
typedef pair<long long, long long> pll;

#define MP make_pair
#define PB push_back
#define ALL(s) (s).begin(),(s).end()
#define EACH(i, s) for (__typeof__((s).begin()) i = (s).begin(); i != (s).end(); ++i)
#define COUT(x) cout << #x << " = " << (x) << " (L" << __LINE__ << ")" << endl

template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }
template<class T1, class T2> ostream& operator << (ostream &s, pair<T1,T2> P) 
{ return s << '<' << P.first << ", " << P.second << '>'; }
template<class T> ostream& operator << (ostream &s, vector<T> P) 
{ for (int i = 0; i < P.size(); ++i) { if (i > 0) { s << " "; } s << P[i]; } return s; }
template<class T> ostream& operator << (ostream &s, vector<vector<T> > P) 
{ for (int i = 0; i < P.size(); ++i) { s << endl << P[i]; } return s << endl; }
template<class T1, class T2> ostream& operator << (ostream &s, map<T1,T2> P) 
{ EACH(it, P) { s << "<" << it->first << "->" << it->second << "> "; } return s; }



/*
今回は、常に、
a側: Win or Draw
b側: Lose or Draw
がわかっているので, Win or Loseの判定は要らない -> adp, bdpの初期化が-INF, INFでよい. 
*/

const int INF = 1<<29;
int CASE;
int n, sa, sb;
int G[55][55];

int adp[55][55];
int bdp[55][55];
bool aknown[55][55];
bool bknown[55][55];

int solve() {
    cin >> n;
    for (int i = 0; i < n; ++i) for (int j = 0; j < n; ++j) cin >> G[i][j];

    cin >> sa >> sb;
    for (int i = 0; i < 55; ++i) for (int j = 0; j < 55; ++j) adp[i][j] = -1, bdp[i][j] = -1;
    for (int i = 0; i < 55; ++i) for (int j = 0; j < 55; ++j) if (G[i][j] || i == j) bdp[i][j] = 1;
    
    int LIM = n*n + 1;
    bool update = false;
    for (int ite = 0; ite <= LIM; ++ite) {
        update = false;
        
        // A's turn
        for (int i = 0; i < n; ++i) for (int j = 0; j < n; ++j) {
            if (i == j) continue;
            int Max = -INF;
            bool unknown = false;
            for (int k = 0; k < n; ++k) {
                if (G[i][k] == 0 && i != k) continue;
                if (bdp[k][j] == -1) { unknown = true; continue; }
                chmax(Max, bdp[k][j] + 1);
            }
            if (Max > -INF && !unknown) {
                if (adp[i][j] == -1) { adp[i][j] = Max; update = true; }
                else if (chmax(adp[i][j], Max)) update = true;
            }
        }
        
        // B's tuen
        for (int i = 0; i < n; ++i) for (int j = 0; j < n; ++j) {
            if (i == j) continue;
            int Min = INF;
            for (int k = 0; k < n; ++k) {
                if (G[j][k] == 0) continue;
                if (adp[i][k] == -1) { continue; }
                chmin(Min, adp[i][k] + 1);
            }
            if (Min < INF) {
                if (bdp[i][j] == -1) { bdp[i][j] = Min; update = true; }
                else if (chmin(bdp[i][j], Min)) update = true;
            }
        }

        if (!update) break;
    }

    if (adp[sa][sb] == -1) return -1;
    else return adp[sa][sb]/2;
}

int main() {
    cin >> CASE;
    for (int AAA = 0; AAA < CASE; ++AAA) {
        int res = solve();
        if (res != -1) cout << res << endl;
        else puts("infinity");
    }
    return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 1200
final_rank: 2

code_snippet: #include <iostream>
#include <sstream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <cstring>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <set>
#include <bitset>
#include <numeric>
#include <utility>
#include <iomanip>
#include <algorithm>
#include <functional>
using namespace std;

typedef long long ll;
typedef vector<int> vint;
typedef vector<long long> vll;
typedef pair<int,int> pint;
typedef pair<long long, long long> pll;

#define MP make_pair
#define PB push_back
#define ALL(s) (s).begin(),(s).end()
#define EACH(i, s) for (__typeof__((s).begin()) i = (s).begin(); i != (s).end(); ++i)
#define COUT(x) cout << #x << " = " << (x) << " (L" << __LINE__ << ")" << endl

template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }
template<class T1, class T2> ostream& operator << (ostream &s, pair<T1,T2> P) 
{ return s << '<' << P.first << ", " << P.second << '>'; }
template<class T> ostream& operator << (ostream &s, vector<T> P) 
{ for (int i = 0; i < P.size(); ++i) { if (i > 0) { s << " "; } s << P[i]; } return s; }
template<class T> ostream& operator << (ostream &s, vector<vector<T> > P) 
{ for (int i = 0; i < P.size(); ++i) { s << endl << P[i]; } return s << endl; }
template<class T1, class T2> ostream& operator << (ostream &s, map<T1,T2> P) 
{ EACH(it, P) { s << "<" << it->first << "->" << it->second << "> "; } return s; }



/*
今回は、常に、
a側: Win or Draw
b側: Lose or Draw
がわかっているので, Win or Loseの判定は要らない -> adp, bdpの初期化が-INF, INFでよい. 
*/

const int INF = 1<<29;
int CASE;
int n, sa, sb;
int G[55][55];

int adp[55][55]; // 逃げる, 最大化を狙う
int bdp[55][55]; // おいかける, 最小化を狙う
bool aknown[55][55];
bool bknown[55][55];

int solve() {
    cin >> n;
    for (int i = 0; i < n; ++i) for (int j = 0; j < n; ++j) cin >> G[i][j];

    cin >> sa >> sb;
    for (int i = 0; i < 55; ++i) for (int j = 0; j < 55; ++j) adp[i][j] = -1, bdp[i][j] = -1;
    for (int i = 0; i < 55; ++i) for (int j = 0; j < 55; ++j) if (G[i][j] || i == j) bdp[i][j] = 1;
    
    int LIM = n*n + 1;
    bool update = false;
    for (int ite = 0; ite <= LIM; ++ite) {
        update = false;
        
        // A's turn
        for (int i = 0; i < n; ++i) for (int j = 0; j < n; ++j) {
            if (i == j) continue;
            int Max = -INF;
            bool unknown = false;
            for (int k = 0; k < n; ++k) {
                if (G[i][k] == 0 && i != k) continue;
                if (bdp[k][j] == -1) { unknown = true; continue; }
                chmax(Max, bdp[k][j] + 1);
            }
            if (Max > -INF && !unknown) {
                if (adp[i][j] == -1) { adp[i][j] = Max; update = true; }
                else if (chmax(adp[i][j], Max)) update = true;
            }
        }
        
        // B's tuen
        for (int i = 0; i < n; ++i) for (int j = 0; j < n; ++j) {
            if (i == j) continue;
            int Min = INF;
            for (int k = 0; k < n; ++k) {
                if (G[j][k] == 0) continue;
                if (adp[i][k] == -1) { continue; }
                chmin(Min, adp[i][k] + 1);
            }
            if (Min < INF) {
                if (bdp[i][j] == -1) { bdp[i][j] = Min; update = true; }
                else if (chmin(bdp[i][j], Min)) update = true;
            }
        }

        if (!update) break;
    }

    if (adp[sa][sb] == -1) return -1;
    else return adp[sa][sb]/2;
}

int main() {
    cin >> CASE;
    for (int AAA = 0; AAA < CASE; ++AAA) {
        int res = solve();
        if (res != -1) cout << res << endl;
        else puts("infinity");
    }
    return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 1200
final_rank: 3

code_snippet: #include <iostream>
#include <sstream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <cstring>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <set>
#include <bitset>
#include <numeric>
#include <utility>
#include <iomanip>
#include <algorithm>
#include <functional>
using namespace std;

typedef long long ll;
typedef vector<int> vint;
typedef vector<long long> vll;
typedef pair<int,int> pint;
typedef pair<long long, long long> pll;

#define MP make_pair
#define PB push_back
#define ALL(s) (s).begin(),(s).end()
#define EACH(i, s) for (__typeof__((s).begin()) i = (s).begin(); i != (s).end(); ++i)
#define COUT(x) cout << #x << " = " << (x) << " (L" << __LINE__ << ")" << endl

template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }
template<class T1, class T2> ostream& operator << (ostream &s, pair<T1,T2> P) 
{ return s << '<' << P.first << ", " << P.second << '>'; }
template<class T> ostream& operator << (ostream &s, vector<T> P) 
{ for (int i = 0; i < P.size(); ++i) { if (i > 0) { s << " "; } s << P[i]; } return s; }
template<class T> ostream& operator << (ostream &s, vector<vector<T> > P) 
{ for (int i = 0; i < P.size(); ++i) { s << endl << P[i]; } return s << endl; }
template<class T1, class T2> ostream& operator << (ostream &s, map<T1,T2> P) 
{ EACH(it, P) { s << "<" << it->first << "->" << it->second << "> "; } return s; }



/*
今回は、常に、
a側: Win or Draw
b側: Lose or Draw
がわかっているので, Win or Loseの判定は要らない -> adp, bdpの初期化が-INF, INFでよい. 
*/

const int INF = 1<<29;
int CASE;
int n, sa, sb;
int G[55][55];

int adp[55][55]; // 逃げる, 最大化を狙う
int bdp[55][55]; // おいかける, 最小化を狙う
bool aknown[55][55];
bool bknown[55][55];

int solve() {
    cin >> n;
    for (int i = 0; i < n; ++i) for (int j = 0; j < n; ++j) cin >> G[i][j];

    cin >> sa >> sb;
    for (int i = 0; i < 55; ++i) for (int j = 0; j < 55; ++j) adp[i][j] = -1, bdp[i][j] = -1;
    for (int i = 0; i < 55; ++i) for (int j = 0; j < 55; ++j) if (G[i][j] || i == j) bdp[i][j] = 1;
    
    int LIM = n*n*2 + 10;
    bool update = false;
    for (int ite = 0; ite <= LIM; ++ite) {
        update = false;
        
        // A's turn
        for (int i = 0; i < n; ++i) for (int j = 0; j < n; ++j) {
            if (i == j) continue;
            int Max = -INF;
            bool unknown = false;
            for (int k = 0; k < n; ++k) {
                if (G[i][k] == 0 && i != k) continue;
                if (bdp[k][j] == -1) { unknown = true; continue; }
                chmax(Max, bdp[k][j] + 1);
            }
            if (Max > -INF && !unknown) {
                if (adp[i][j] == -1) { adp[i][j] = Max; update = true; }
                else if (chmax(adp[i][j], Max)) update = true;
            }
        }
        
        // B's tuen
        for (int i = 0; i < n; ++i) for (int j = 0; j < n; ++j) {
            if (i == j) continue;
            int Min = INF;
            for (int k = 0; k < n; ++k) {
                if (G[j][k] == 0) continue;
                if (adp[i][k] == -1) { continue; }
                chmin(Min, adp[i][k] + 1);
            }
            if (Min < INF) {
                if (bdp[i][j] == -1) { bdp[i][j] = Min; update = true; }
                else if (chmin(bdp[i][j], Min)) update = true;
            }
        }
        
        //cout << endl; COUT(ite);
        //for (int i = 0; i < n; ++i) for (int j = 0; j < n; ++j) cout << pint(i, j) << " : " << pint(adp[i][j], bdp[i][j]) << endl;
        
        if (!update) break;
    }
    
    //for (int i = 0; i < n; ++i) for (int j = 0; j < n; ++j) cout << pint(i, j) << " : " << pint(adp[i][j], bdp[i][j]) << endl;
    
    if (adp[sa][sb] == -1) return -1;
    else return adp[sa][sb]/2;
}

int main() {
    cin >> CASE;
    for (int AAA = 0; AAA < CASE; ++AAA) {
        int res = solve();
        if (res != -1) cout << res << endl;
        else puts("infinity");
    }
    return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 1200
final_rank: 3

code_snippet: #include <iostream>
#include <sstream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <cstring>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <set>
#include <bitset>
#include <numeric>
#include <utility>
#include <iomanip>
#include <algorithm>
#include <functional>
using namespace std;

typedef long long ll;
typedef vector<int> vint;
typedef vector<long long> vll;
typedef pair<int,int> pint;
typedef pair<long long, long long> pll;

#define MP make_pair
#define PB push_back
#define ALL(s) (s).begin(),(s).end()
#define EACH(i, s) for (__typeof__((s).begin()) i = (s).begin(); i != (s).end(); ++i)
#define COUT(x) cout << #x << " = " << (x) << " (L" << __LINE__ << ")" << endl

template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }
template<class T1, class T2> ostream& operator << (ostream &s, pair<T1,T2> P) 
{ return s << '<' << P.first << ", " << P.second << '>'; }
template<class T> ostream& operator << (ostream &s, vector<T> P) 
{ for (int i = 0; i < P.size(); ++i) { if (i > 0) { s << " "; } s << P[i]; } return s; }
template<class T> ostream& operator << (ostream &s, vector<vector<T> > P) 
{ for (int i = 0; i < P.size(); ++i) { s << endl << P[i]; } return s << endl; }
template<class T1, class T2> ostream& operator << (ostream &s, map<T1,T2> P) 
{ EACH(it, P) { s << "<" << it->first << "->" << it->second << "> "; } return s; }



/*
今回は、常に、
a側: Win or Draw
b側: Lose or Draw
がわかっているので, Win or Loseの判定は要らない -> adp, bdpの初期化が-INF, INFでよい. 
*/

const int INF = 1<<29;
int CASE;
int n, sa, sb;
int G[101][101];

int adp[55][55]; // 逃げる, 最大化を狙う
int bdp[55][55]; // おいかける, 最小化を狙う
bool aknown[55][55];
bool bknown[55][55];

int solve() {
    cin >> n;
    for (int i = 0; i < n; ++i) for (int j = 0; j < n; ++j) cin >> G[i][j];

    cin >> sa >> sb;
    for (int i = 0; i < 55; ++i) for (int j = 0; j < 55; ++j) adp[i][j] = -INF, bdp[i][j] = INF;
    for (int i = 0; i < 55; ++i) for (int j = 0; j < 55; ++j) if (G[i][j] || i == j) bdp[i][j] = 1;
    
    int LIM = n*n*2 + 10;
    bool update = false;
    for (int ite = 0; ite <= LIM; ++ite) {
        update = false;
        
        // A's turn
        for (int i = 0; i < n; ++i) for (int j = 0; j < n; ++j) {
            if (i == j) continue;
            int Max = -INF;
            bool unknown = false;
            for (int k = 0; k < n; ++k) {
                if (G[i][k] == 0 && i != k) continue;
                if (bdp[k][j] >= INF) { unknown = true; continue; }
                chmax(Max, bdp[k][j] + 1);
            }
            if (Max > -INF && !unknown) if (chmax(adp[i][j], Max)) update = true;
        }
        
        // B's tuen
        for (int i = 0; i < n; ++i) for (int j = 0; j < n; ++j) {
            if (i == j) continue;
            int Min = INF;
            for (int k = 0; k < n; ++k) {
                if (G[j][k] == 0) continue;
                if (adp[i][k] <= -INF) { continue; }
                chmin(Min, adp[i][k] + 1);
            }
            if (Min < bdp[i][j]) update = true;
            if (Min < INF) if (chmin(bdp[i][j], Min)) update = true;
        }
        
        //cout << endl; COUT(ite);
        //for (int i = 0; i < n; ++i) for (int j = 0; j < n; ++j) cout << pint(i, j) << " : " << pint(adp[i][j], bdp[i][j]) << endl;
        
        if (!update) break;
    }
    
    //for (int i = 0; i < n; ++i) for (int j = 0; j < n; ++j) cout << pint(i, j) << " : " << pint(adp[i][j], bdp[i][j]) << endl;
    
    if (adp[sa][sb] == -INF) return -1;
    else return adp[sa][sb]/2;
}

int main() {
    //freopen( "/Users/macuser/Dropbox/Contest/input.in", "r", stdin );
    
    cin >> CASE;
    for (int AAA = 0; AAA < CASE; ++AAA) {
        int res = solve();
        if (res != -1) cout << res << endl;
        else puts("infinity");
    }
    return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 1212
final_rank: 5

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

#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)

using namespace std;


const int IINF = INT_MAX;
const int MAX_V = 60;
int V,initial_Aaron,initial_Bruce,memo[MAX_V][MAX_V][2];
vector<int> G[MAX_V];

#define REPEAT -1

void compute(){
  rep(i,V) rep(j,V) rep(k,2) memo[i][j][k] = REPEAT;
  rep(i,V) memo[i][i][0] = memo[i][i][1] = 0;
  
  bool update = true;
  while( update ){
    update = false;
    rep(Aaron,V){
      rep(Bruce,V){
	rep(phase,2){
	  if( phase ) { // Bruce
	    int mini = IINF;
	    rep(i,(int)G[Bruce].size()+1){
	      int next = ((i==G[Bruce].size())?Bruce:G[Bruce][i]);
	      if( memo[Aaron][next][!phase] != REPEAT ) { mini = min(mini,memo[Aaron][next][!phase]); }
	    }
	    if( mini != IINF && ( memo[Aaron][Bruce][phase] == REPEAT || memo[Aaron][Bruce][phase] > mini + 1 ) ) memo[Aaron][Bruce][phase] = mini + 1, update = true;
	  } else {      // Aaron
	    bool escape = false;
	    int maxi = -IINF;
	    rep(i,(int)G[Aaron].size()+1){
	      int next = ((i==G[Aaron].size())?Aaron:G[Aaron][i]);
	      if( memo[next][Bruce][!phase] == REPEAT ) { escape = true; }
	      if( memo[next][Bruce][!phase] != REPEAT ) { maxi = max(maxi,memo[next][Bruce][!phase]); }
	    }
	    if( !escape && maxi != -IINF && ( memo[Aaron][Bruce][phase] == REPEAT || memo[Aaron][Bruce][phase] < maxi + 1 ) ) {
	      memo[Aaron][Bruce][phase] = maxi + 1, update = true;
	    }
	  }
	}
      }
    }
  }
  if( memo[initial_Aaron][initial_Bruce][0] == REPEAT ) puts("infinity");
  else printf("%d\n",(int)ceil(memo[initial_Aaron][initial_Bruce][0]/2.0));
}

int main(){
  int T;
  cin >> T;
  while( T-- ){
    cin >> V;
    rep(i,V) G[i].clear();
    rep(cur,V) {
      rep(next,V) {
	int edge;
	cin >> edge;
	if( edge ) G[cur].push_back(next);
      }
    }
    cin >> initial_Aaron >> initial_Bruce;
    compute();
  }
  return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 1248
final_rank: 1

code_snippet: #include<stdio.h>
#include<algorithm>
using namespace std;
short dp[5010][60][60];
int g[60][60];
int n;
int solve(int a,int b,int c){
	if(dp[a][b][c]>=0)return dp[a][b][c];
	if(b==c)return dp[a][b][c]=a;
	if(a==2*n){
		return dp[a][b][c]=a;
	}
	if(a%2==0){
		int ret=0;
		for(int i=0;i<n;i++){
			if(g[b][i]){
				ret=max(ret,solve(a+1,i,c));
			}
		}
	//	printf("%d %d %d: %d\n",a,b,c,ret);
		return dp[a][b][c]=ret;
	}else{
		int ret=2*n;
		for(int i=0;i<n;i++){
			if(g[c][i])ret=min(ret,solve(a+1,b,i));
		}
	//	printf("%d %d %d: %d\n",a,b,c,ret);
		return dp[a][b][c]=ret;
	}
}
int main(){
	int T;scanf("%d",&T);
	while(T--){
		int a;scanf("%d",&a);
		n=a;
		for(int i=0;i<a;i++)for(int j=0;j<a;j++)scanf("%d",&g[i][j]);
		for(int i=0;i<=2*a;i++)for(int j=0;j<a;j++)for(int k=0;k<a;k++)dp[i][j][k]=-1;
		for(int i=0;i<a;i++)g[i][i]=1;
		int s,t;scanf("%d%d",&s,&t);
		solve(0,s,t);
		int ret=solve(0,s,t)/2;
		if(ret==a)printf("infinity\n");
		else printf("%d\n",ret);
	}
}
accuracy: 1
time_ms: 180
memory_kb: 1764
final_rank: 9

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

template<class T> inline void chmin(T &a, const T &b) { if(a > b) a = b; }
template<class T> inline void chmax(T &a, const T &b) { if(a < b) a = b; }

typedef vector<vector<int>> graph;

constexpr int INF = (1 << 29);
constexpr int MAX_N = 50;

enum {A, B, NUM};
int dp[MAX_N][MAX_N][NUM];

inline string solve() {
	int n;
	cin >> n;

	graph G(n);
	for(int v = 0; v < n; ++v) {
		G[v].emplace_back(v);
		for(int u = 0; u < n; ++u) {
			int exist;
			cin >> exist;
			if(exist) G[v].emplace_back(u);
		}
	}

	fill_n((int *)dp, sizeof(dp) / sizeof(int), INF);
	for(int v = 0; v < n; ++v) {
		dp[v][v][A] = dp[v][v][B] = 0;
	}

	for(int iter = 0; iter < 2 * n; ++iter) {
		for(int v = 0; v < n; ++v) {
			for(int u = 0; u < n; ++u) {
				if(v == u) continue;

				// Aaron turn
				dp[v][u][A] = 0;
				for(const auto &to : G[v]) {
					chmax(dp[v][u][A], dp[to][u][B]);
				}

				// Bruce turn
				for(const auto &to : G[u]) {
					chmin(dp[v][u][B], dp[v][to][A] + 1);
				}
			}
		}
	}

	int a, b;
	cin >> a >> b;

	return dp[a][b][A] >= n ? "infinity" : to_string(dp[a][b][A]);
}

int main() {
	cin.tie(nullptr);
	ios::sync_with_stdio(false);

	int T;
	cin >> T;
	while(T--) cout << solve() << endl;

	return EXIT_SUCCESS;
}
accuracy: 1
time_ms: 90
memory_kb: 1292
final_rank: 7

code_snippet: #include <iostream>
#include <sstream>
#include <string>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cassert>

using namespace std;

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

template<class T> void debug(T begin, T end){ for(T i = begin; i != end; ++i) cerr<<*i<<" "; cerr<<endl; }
inline bool valid(int x, int y, int W, int H){ return (x >= 0 && y >= 0 && x < W && y < H); }

typedef long long ll;
const int INF = 100000000;
const double EPS = 1e-8;
const int MOD = 1000000007;
int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};
int memo[50][50][2];
int dfs(int a, int b, int turn, const vector< vector<int> >& G){
  if(memo[a][b][turn] != -1) return memo[a][b][turn];
  if(a == b) return memo[a][b][turn] = 0;
  memo[a][b][turn] = INF;
  if(turn == 0){
    // Aaron - escape
    int res = dfs(a, b, turn ^ 1, G);
    FORIT(u, G[a]){
      int next = dfs(*u, b, turn ^ 1, G);
      res = max(res, next);
    }
    return memo[a][b][turn] = res;
  }else{
    // Bruce - chase
    int res = 1 + dfs(a, b, turn ^ 1, G);
    FORIT(u, G[b]){
      int next = dfs(a, *u, turn ^ 1, G);
      res = min(res, 1 + next);
    }
    return memo[a][b][turn] = res;
  }
}

int main(){
  int T; cin >> T;
  while(T--){
    int N; cin >> N;
    vector< vector<int> > G(N);
    REP(i, N)REP(j, N){
      int t; cin >> t;
      if(t) G[i].push_back(j);
    }
    REP(i, N) G[i].push_back(i);
    int sa, sb;
    cin >> sa >> sb;
    //memset(memo, -1, sizeof(memo));
    //int ans = dfs(a, b, 0, G);
    int dp[50][50][2] = {};
    memset(dp, -1, sizeof(dp));
    REP(i, N) dp[i][i][0] = 0;
    REP(iter, 1000){
      for(int a = 0; a < N; a++){
        for(int b = 0; b < N; b++){
          if(a == b) continue;
          dp[a][b][0] = -1;
          REP(i, G[a].size()){
            int u = G[a][i];
            if(dp[u][b][1] != -1){
              if(dp[a][b][0] == -1 || dp[a][b][0] < dp[u][b][1]) dp[a][b][0] = dp[u][b][1];
            }
          }
          dp[a][b][1] = -1;
          REP(i, G[b].size()){
            int u = G[b][i];
            if(dp[a][u][0] != -1){
              if(dp[a][b][1] == -1 || dp[a][b][1] > 1 + dp[a][u][0]){
                dp[a][b][1] = 1 + dp[a][u][0];
              }
            }
          }
        }
      }
    }
    //REP(a, N) REP(b, N) REP(turn, 2) printf("(%d, %d, %d) = %d\n", a, b, turn, dp[a][b][turn]);
    int ans = dp[sa][sb][0];
    if(ans >= N || ans == -1) cout << "infinity" << endl;
    else cout << ans << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 1610
memory_kb: 1260
final_rank: 17

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

const int T_MAX = 401;
const int INF = 1e+8;
int M, g[51][51];
// dp[i][j][t] := (i,j) = (Aaronの位置,Bruceの位置), ターン数 t のときの
int dp[51][51][T_MAX];

// 初期化
void init(){
	for(int i=0 ; i < 51 ; i++ ){
		for(int j=0 ; j < 51 ; j++ ){
			g[i][j] = 0;
			for(int k=0 ; k < T_MAX ; k++ ){
				dp[i][j][k] = -1;
			}
		}
	}
}

// (a,b) = (Aaronの位置,Bruceの位置), t : ターン数
int dfs(int a, int b, int t){
	if( a == b ) return t;
	if( t >= T_MAX ) return INF;
	if( dp[a][b][t] >= 0 ) return dp[a][b][t];
	
	if( t % 2 == 0 ){ // 偶数ターン(Aaronが動く)
		dp[a][b][t] = 0;
		for(int i=0 ; i < M ; i++ ){
			if( g[a][i] ){
				dp[a][b][t] = max( dp[a][b][t] , dfs(i,b,t+1) );
			}
		}
		return dp[a][b][t];
	}else{ // 奇数ターン(Bruceが動く)
		dp[a][b][t] = INF;
		for(int i=0 ; i < M ; i++ ){
			if( g[b][i] ){
				dp[a][b][t] = min( dp[a][b][t] , dfs(a,i,t+1) );
			}
		}
		return dp[a][b][t];
	}
}

int main(){
	int T;
	cin >> T;
	for(int t_ = 0 ; t_ < T ; t_++ ){
		// 初期化
		init();
		
		cin >> M;
		for(int i=0 ; i < M ; i++ ){
			for(int j=0 ; j < M ; j++ ){
				cin >> g[i][j];
				if( i == j ) g[i][j] = 1;
			}
		}
		int a, b;
		cin >> a >> b;
		int ans = dfs(a,b,0);
		if( ans > T_MAX ){
			cout << "infinity" << endl;
		}else{
			cout << ans/2 << endl;
		}
	}
}
accuracy: 1
time_ms: 1240
memory_kb: 5272
final_rank: 16

code_snippet: #include <iostream>
#include <iomanip>
#include <sstream>
#include <cstdio>
#include <string>
#include <vector>
#include <algorithm>
#include <complex>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <cassert>
#include <climits>
#include <queue>
#include <set>
#include <map>
#include <valarray>
#include <bitset>
#include <stack>
using namespace std;

#define REP(i,n) for(int i=0;i<(int)n;++i)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)
#define ALL(c) (c).begin(), (c).end()
typedef long long ll;
typedef pair<int,int> pii;
const int INF = 1<<29;
const double PI = acos(-1);
const double EPS = 1e-8;

bool adj[100][100];
int n;
int memo[100][100][500];
int solve(int a, int b, int t) {
  int f = t%2;
  if (memo[a][b][t] >= 0) return memo[a][b][t];
  if (a == b) return 0;
  if (t > 500) return INF;
  //cout << a << " "  << b << " " << t << endl;
  int res;
  if (f) {                      // aaron
    res = 0;
    REP(i,n) {
      if (adj[a][i]) {
        res = max(res,solve(i,b,t+1)+1);
      }
    }
  } else {
    res = INF;
    REP(i,n) {
      if (adj[b][i]) {
        res = min(res, solve(a,i,t+1));
      }
    }
  }
  return memo[a][b][t] = res;
}


int main() {
  int T;
  cin >> T;
  while(T--) {
    cin >> n;
    REP(i,n) REP(j,n)
      cin >> adj[i][j];
    REP(i,n) adj[i][i] = 1;
    // REP(i,n) {
    //   REP(j,n)cout<<dis[i][j]<< " "; cout << endl;
    // }
    int A, B; cin >> A >> B;
    memset(memo,-1,sizeof(memo));
    int ret = solve(A,B,1);
    if (ret > 2000) cout << "infinity" << endl;
    else cout << ret << endl;
    
  }
}
accuracy: 1
time_ms: 2960
memory_kb: 0
final_rank: 19

code_snippet: #include <iostream>
#include <cstring>
using namespace std;
#define INF (1<<25)
int dp[60][50][50][2] = {};
int g[50][50] = {};
int n,m;

int dfs(int mid,int a,int b,int t){
	if(t == 0 && a == b) return -INF;
	if(dp[mid][a][b][t] != -1) return dp[mid][a][b][t];
	if(mid == 0){
		//cout << a << " " << b << " " << t << endl;
		return 0;
	}
	if(t==0){
		int ans = -INF;
		for(int i = 0 ; i < n ; i++)
			if(g[a][i]) ans = max(ans,dfs(mid,i,b,t^1));
		return dp[mid][a][b][t] = ans;
	}else{
		int ans = INF;
		for(int i = 0 ; i < n ; i++)
			if(g[b][i]) ans = min(ans,dfs(mid-1,a,i,t^1)+1);
		return dp[mid][a][b][t] = ans;
	}
}
int main(){
	int T; cin >> T;
	while(T--){
		cin >> n;
		int a,b;
		for(int i = 0 ; i < n ; i++)
			for(int j = 0 ; j < n ; j++)
				cin >> g[i][j];
		for(int i = 0 ; i < n ; i++)
			g[i][i] = 1;
		cin >> a >> b;
		
		memset(dp,-1,sizeof(dp));
		int l = 0 , r = 52;
		while(l!=r){
			int mid = (l+r+1) / 2;
			if( dfs(mid,a,b,0) >= 0 ) l = mid;
			else r = mid-1;
		}
		if(l==52) cout << "infinity" << endl;
		else cout << l+1 << endl;
	}
}
accuracy: 1
time_ms: 290
memory_kb: 2048
final_rank: 10

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>

using namespace std;

int n;
int T;
int sa,sb;
vector<int> G[51];
int dp[201][51][51];
const int INF=1000000000;


int main(){

    cin>>T;
    while(T--){
        cin>>n;
        memset(dp,-1,sizeof(dp));
        for(int i=0;i<n;i++)G[i].clear();
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                int a;
                cin>>a;
                if(a==1){
                    G[i].push_back(j);
                    G[j].push_back(i);
                }
            }
        }
        cin>>sa>>sb;
        for(int i=0;i<n;i++)for(int j=0;j<n;j++)dp[0][i][j]=INF;
        for(int i=200-1;i>=0;i--){
            for(int j=0;j<n;j++){
                for(int k=0;k<n;k++){
                    int res=INF;
                    int tern=i;
                    int apos=j;
                    int bpos=k;
                    int cur=(i+1)%2;
                    int nxt=i%2;
                    if(apos==bpos){
                        dp[nxt][j][k]=i/2;
                        continue;
                    }
                    if(tern%2==0)res=0;
                    if(tern%2==0){
                        for(int l=0;l<G[apos].size();l++){
                            int to=G[apos][l];
                            res=max(res,dp[cur][to][bpos]);
                        }
                        res=max(res,dp[cur][apos][bpos]);
                    }
                    else{
                        for(int l=0;l<G[bpos].size();l++){
                            int to=G[bpos][l];
                            res=min(res,dp[cur][apos][to]);
                        }
                        res=min(res,dp[cur][apos][bpos]);
                    }
                    dp[nxt][j][k]=res;
                }
            }
        }

        int res=dp[0][sa][sb];
        if(res==INF)cout<<"infinity"<<endl;
        else cout<<res<<endl;
    }

    return 0;
}
accuracy: 1
time_ms: 340
memory_kb: 2976
final_rank: 12

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>

using namespace std;

int n;
int T;
int sa,sb;
vector<int> G[51];
int dp[201][51][51];
const int INF=1000000000;

int dfs(int tern,int apos,int bpos){
    if(tern==200)return INF;
    else if(apos==bpos)return tern/2;
    if(dp[tern][apos][bpos]!=-1)return dp[tern][apos][bpos];
    int res=INF;
    if(tern%2==0)res=0;
    if(tern%2==0){
        for(int i=0;i<G[apos].size();i++){
            int to=G[apos][i];
            res=max(res,dfs(tern+1,to,bpos));
        }
        res=max(res,dfs(tern+1,apos,bpos));
    }
    else{
        for(int i=0;i<G[bpos].size();i++){
            int to=G[bpos][i];
            res=min(res,dfs(tern+1,apos,to));
        }
            res=min(res,dfs(tern+1,apos,bpos));
    }
    return dp[tern][apos][bpos]=res;
}

int main(){

    cin>>T;
    while(T--){
        cin>>n;
        memset(dp,-1,sizeof(dp));
        for(int i=0;i<n;i++)G[i].clear();
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                int a;
                cin>>a;
                if(a==1){
                    G[i].push_back(j);
                    G[j].push_back(i);
                }
            }
        }
        cin>>sa>>sb;
        int res=dfs(0,sa,sb);
        if(res==INF)cout<<"infinity"<<endl;
        else cout<<res<<endl;
    }

    return 0;
}
accuracy: 1
time_ms: 1100
memory_kb: 2980
final_rank: 14