B.Harborfan的新年拜访Ⅱ
就是一道tarjan缩点的裸题。
建图比较麻烦
以后遇到这种建图,先用循环把样例实现出来,再对着循环写建图公式
#include<bits/stdc++.h> using namespace std; const int maxn=1014; vector<int> g[maxn]; string s1,s2; int N,M; int low[maxn]; int dfn[maxn]; int pos[maxn]; stack<int> st; int scc; int cnt; void tarjan (int x) { low[x]=dfn[x]=++cnt; st.push(x); for (int i=0;i<g[x].size();i++) { if (!low[g[x][i]]) { tarjan(g[x][i]); low[x]=min(low[x],low[g[x][i]]); } else if (!pos[g[x][i]])low[x]=min(low[x],dfn[g[x][i]]); } if (low[x]==dfn[x]) { scc++; while (1) { int u=st.top(); st.pop(); low[u]=low[x]; pos[u]=scc; if (u==x) break; } } } int main () { scanf ("%d %d",&N,&M); cin>>s1>>s2; /*for (int i=2;i<=6;i++) g[i].push_back(i-1); for (int i=8;i<=12;i++) g[i-1].push_back(i); for (int i=14;i<=18;i++) g[i].push_back(i-1); for (int i=20;i<=24;i++) g[i-1].push_back(i); for (int i=7;i<=19;i+=6) g[i-6].push_back(i); for (int i=8;i<=20;i+=6) g[i].push_back(i-6); for (int i=9;i<=21;i+=6) g[i-6].push_back(i); for (int i=10;i<=22;i+=6) g[i].push_back(i-6); for (int i=11;i<=23;i+=6) g[i-6].push_back(i); for (int i=12;i<=24;i+=6) g[i].push_back(i-6); */ for (int i=0;i<s1.length();i++) { for (int j=i*M+2;j<=(i+1)*M;j++) { if (s1[i]=='>') g[j-1].push_back(j); else g[j].push_back(j-1); } } for (int i=0;i<s2.length();i++) { for (int j=M+i+1;j<=M*(N-1)+1+i;j+=M) { if (s2[i]=='v') g[j-M].push_back(j); else g[j].push_back(j-M); } } for (int i=1;i<=N*M;i++) if (!low[i]) tarjan(i); //printf ("%d\n",scc); if (scc==1) printf ("YES"); else printf ("NO"); return 0; }
E.
爆搜即可,需要注意的是,一个单位代表四面墙,每一次爆搜,把搜到的点记录下来,之后询问就直接输出答案,避免tle~
#include<bits/stdc++.h> using namespace std; const int maxn=1014; string s[maxn]; int g[maxn][maxn]; int N,M,K; struct node { int x,y; }; int X[4]={1,0,-1,0}; int Y[4]={0,1,0,-1}; int visit[maxn][maxn]; int visit1[maxn][maxn][4]; int q1[maxn][maxn]; int judge (int x,int y) { if (x<1||x>N||y<1||y>M) return 0; return 1; } int bfs (int x,int y,int z) { queue<node> q; q.push({x,y}); memset(visit,0,sizeof(visit)); memset(visit1,0,sizeof(visit1)); visit[x][y]=1; int ans=0; q1[x][y]=z; while (!q.empty()) { node u=q.front(); q.pop(); for (int i=0;i<4;i++) { int tx=u.x+X[i]; int ty=u.y+Y[i]; if (!judge(tx,ty)) continue; if (visit[tx][ty]) continue; if (visit1[tx][ty][i]) continue; if (g[tx][ty]==0) { q.push({tx,ty}); visit[tx][ty]=1; q1[tx][ty]=z; continue; } if (g[tx][ty]==1) { ans++; visit1[tx][ty][i]=1; } } } return ans; } int ans[maxn*1000]; int main () { scanf ("%d %d %d",&N,&M,&K); for (int i=1;i<=N;i++) cin>>s[i]; for (int i=1;i<=N;i++) { for (int j=0;j<s[i].length();j++) { g[i][j+1]=s[i][j]=='.'?0:1; } } int x,y; for (int i=0;i<K;i++) { scanf ("%d %d",&x,&y); if (q1[x][y]) { printf ("%d\n",ans[q1[x][y]]); continue; } ans[i+1]=bfs(x,y,i+1); printf ("%d\n",ans[i+1]); } return 0; }