NC7501I (反向建图)
题意:
给出一个方阵,每个格点上的字母表示走到这个格点必须走哪个方向。
询问以多少个点为起点,可以走出去。
题解:
注意到每个点只可能去往一个节点,反向建图可以建一个类似于树的结构,从根节点搜索即可。
//建一个超级源点 //每个点只能去一个地方 //可以以此建边 //空点为根节点 //连完边后从根节点反向搜索 #include<bits/stdc++.h> using namespace std; const int maxn=1e6+100; int n,m; vector<int> g[maxn]; string s[maxn]; int ans=0; void dfs (int u,int pre) { ans++; for (int v:g[u]) { if (v==pre) continue; dfs(v,u); } } int main () { scanf("%d%d",&n,&m); for (int i=0;i<n;i++) cin>>s[i]; for (int i=1;i<=n;i++) { for (int j=1;j<=m;j++) { if (s[i-1][j-1]=='W') { int tx=i-1; int ty=j; if (tx<1||tx>n||ty<1||ty>m) { g[0].push_back((i-1)*m+j); } else { g[(tx-1)*m+ty].push_back((i-1)*m+j); } } else if (s[i-1][j-1]=='A') { int tx=i; int ty=j-1; if (tx<1||tx>n||ty<1||ty>m) { g[0].push_back((i-1)*m+j); } else { g[(tx-1)*m+ty].push_back((i-1)*m+j); } } else if (s[i-1][j-1]=='S') { int tx=i+1; int ty=j; if (tx<1||tx>n||ty<1||ty>m) { g[0].push_back((i-1)*m+j); } else { g[(tx-1)*m+ty].push_back((i-1)*m+j); } } else if (s[i-1][j-1]=='D') { int tx=i; int ty=j+1; if (tx<1||tx>n||ty<1||ty>m) { g[0].push_back((i-1)*m+j); } else { g[(tx-1)*m+ty].push_back((i-1)*m+j); } } } } dfs(0,-1); printf("%d\n",ans-1); }