感 觉 还 是 很 巧 妙 啊 感觉还是很巧妙啊 感觉还是很巧妙啊
设 d p [ x ] [ y ] [ k ] 表 示 先 手 在 x , 后 手 在 y , 上 一 次 边 权 是 k 的 胜 负 情 况 设dp[x][y][k]表示先手在x,后手在y,上一次边权是k的胜负情况 设dp[x][y][k]表示先手在x,后手在y,上一次边权是k的胜负情况
那 么 x 先 手 , 所 以 把 x 能 走 的 所 有 路 走 一 遍 那么x先手,所以把x能走的所有路走一遍 那么x先手,所以把x能走的所有路走一遍
只 要 存 在 一 条 路 赢 了 就 赢 了 , 否 则 输 了 只要存在一条路赢了就赢了,否则输了 只要存在一条路赢了就赢了,否则输了
这 个 过 程 用 记 忆 化 搜 索 很 方 便 实 现 这个过程用记忆化搜索很方便实现 这个过程用记忆化搜索很方便实现
#include <bits/stdc++.h> using namespace std; #define f first #define s second #define pb push_back const int maxn=209; int dp[maxn][maxn][maxn],n,m; typedef pair<int,int>p; vector<p>vec[maxn]; bool DP(int x,int y,int k)//x先手,y后手,当前边权为k { if( dp[x][y][k]!=-1 ) return dp[x][y][k]; for(int i=0;i<vec[x].size();i++) { int v=vec[x][i].f,cost=vec[x][i].s; if(cost>=k&&DP(y,v,cost)==0)//如果y必输 return dp[x][y][k]=1;//x先手必胜 } return dp[x][y][k]=0;//没有x可以赢得路,必须输掉了 } int main() { cin >> n >> m; for(int i=1;i<=m;i++) { int l,r;char w; cin>>l>>r>>w; vec[l].pb(p(r,w)); } memset(dp,-1,sizeof(dp)); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) DP(i,j,0); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { if(dp[i][j][0]) cout<<'A'; else cout<<"B"; if(j==n) cout<<endl; } }