enumclassState{kDraw,kMouseWin,kCatWin};classSolution{public:intcatMouseGame(vector<vector<int>>&graph){constintn=graph.size();// Result of (cat, mouse, move)// Move := 0 (mouse) / 1 (cat)vector<vector<vector<State>>>states(n,vector<vector<State>>(n,vector<State>(2)));vector<vector<vector<int>>>outDegree(n,vector<vector<int>>(n,vector<int>(2)));queue<tuple<int,int,int,State>>q;// (cat, mouse, move, state)for(intcat=0;cat<n;++cat)for(intmouse=0;mouse<n;++mouse){outDegree[cat][mouse][0]=graph[mouse].size();outDegree[cat][mouse][1]=graph[cat].size()-count(begin(graph[cat]),end(graph[cat]),0);}// Start from states that winner can be determinedfor(intcat=1;cat<n;++cat)for(intmove=0;move<2;++move){// Mouse is in the hole -> State::kMouseWinstates[cat][0][move]=State::kMouseWin;q.emplace(cat,0,move,State::kMouseWin);// Cat catches mouse -> State::kCatWinstates[cat][cat][move]=State::kCatWin;q.emplace(cat,cat,move,State::kCatWin);}while(!q.empty()){constauto[cat,mouse,move,state]=q.front();q.pop();if(cat==2&&mouse==1&&move==0)returnstatic_cast<int>(state);constintprevMove=move^1;for(constintprev:graph[prevMove?cat:mouse]){constintprevCat=prevMove?prev:cat;if(prevCat==0)// Invalidcontinue;constintprevMouse=prevMove?mouse:prev;// The state is already determinedif(states[prevCat][prevMouse][prevMove]!=State::kDraw)continue;if(prevMove==0&&state==State::kMouseWin||prevMove==1&&state==State::kCatWin||--outDegree[prevCat][prevMouse][prevMove]==0){states[prevCat][prevMouse][prevMove]=state;q.emplace(prevCat,prevMouse,prevMove,state);}}}returnstatic_cast<int>(states[2][1][0]);}};
enumState{kDraw,kMouseWin,kCatWin}classSolution{publicintcatMouseGame(int[][]graph){finalintn=graph.length;// Result of (cat, mouse, move)// Move := 0 (mouse) / 1 (cat)int[][][]states=newint[n][n][2];int[][][]outDegree=newint[n][n][2];Queue<int[]>q=newArrayDeque<>();for(intcat=0;cat<n;++cat)for(intmouse=0;mouse<n;++mouse){outDegree[cat][mouse][0]=graph[mouse].length;outDegree[cat][mouse][1]=graph[cat].length-(Arrays.stream(graph[cat]).anyMatch(v->v==0)?1:0);}// Start from states that winner can be determinedfor(intcat=1;cat<n;++cat)for(intmove=0;move<2;++move){// Mouse is in the hole -> MOUSE WINstates[cat][0][move]=State.kMouseWin.ordinal();q.offer(newint[]{cat,0,move,State.kMouseWin.ordinal()});// Cat catches mouse -> kCatWinstates[cat][cat][move]=State.kCatWin.ordinal();q.offer(newint[]{cat,cat,move,State.kCatWin.ordinal()});}while(!q.isEmpty()){finalintcat=q.peek()[0];finalintmouse=q.peek()[1];finalintmove=q.peek()[2];finalintstate=q.poll()[3];if(cat==2&&mouse==1&&move==0)returnstate;finalintprevMove=move^1;for(finalintprev:graph[prevMove==0?mouse:cat]){finalintprevCat=prevMove==0?cat:prev;if(prevCat==0)// Invalidcontinue;finalintprevMouse=prevMove==0?prev:mouse;// The state is already determinedif(states[prevCat][prevMouse][prevMove]>0)continue;if(prevMove==0&&state==State.kMouseWin.ordinal()||prevMove==1&&state==State.kCatWin.ordinal()||--outDegree[prevCat][prevMouse][prevMove]==0){states[prevCat][prevMouse][prevMove]=state;q.offer(newint[]{prevCat,prevMouse,prevMove,state});}}}returnstates[2][1][0];}}
fromenumimportIntEnumclassState(IntEnum):kDraw=0kMouseWin=1kCatWin=2classSolution:defcatMouseGame(self,graph:List[List[int]])->int:n=len(graph)# Result of (cat, mouse, move)# Move := 0 (mouse) // 1 (cat)states=[[[0]*2foriinrange(n)]forjinrange(n)]outDegree=[[[0]*2foriinrange(n)]forjinrange(n)]q=deque()# (cat, mouse, move, state)forcatinrange(n):formouseinrange(n):outDegree[cat][mouse][0]=len(graph[mouse])outDegree[cat][mouse][1]=len(graph[cat])-graph[cat].count(0)# Start from states that winner can be determinedforcatinrange(1,n):formoveinrange(2):# Mouse is in the hole . kMouseWinstates[cat][0][move]=int(State.kMouseWin)q.append((cat,0,move,int(State.kMouseWin)))# Cat catches mouse . kCatWinstates[cat][cat][move]=int(State.kCatWin)q.append((cat,cat,move,int(State.kCatWin)))whileq:cat,mouse,move,state=q.popleft()ifcat==2andmouse==1andmove==0:returnstateprevMove=move^1forprevingraph[catifprevMoveelsemouse]:prevCat=previfprevMoveelsecatifprevCat==0:# InvalidcontinueprevMouse=mouseifprevMoveelseprev# The state is already determinedifstates[prevCat][prevMouse][prevMove]:continueifprevMove==0andstate==int(State.kMouseWin)or \
prevMove==1andstate==int(State.kCatWin):states[prevCat][prevMouse][prevMove]=stateq.append((prevCat,prevMouse,prevMove,state))else:outDegree[prevCat][prevMouse][prevMove]-=1ifoutDegree[prevCat][prevMouse][prevMove]==0:states[prevCat][prevMouse][prevMove]=stateq.append((prevCat,prevMouse,prevMove,state))returnstates[2][1][0]