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;
}