题意:给定一张 n(≤3×103) 个点的无向图(邻接矩阵),求 p 到每个点(不包括 p)必经的点有哪些(不包括起点和终点)。
样例: in:
7 1
0 0 0 0 1 0 0
0 0 0 1 0 1 1
0 0 0 0 0 1 0
0 1 0 0 1 0 0
1 0 0 1 0 1 0
0 1 1 0 1 0 0
0 1 0 0 0 0 0
out:
5
5 6
5
No
5
2 5
#include<bits/stdc++.h>
using namespace std;
const int N=4010,M=2e7+10;
int n,p,e[N][N],vis[N],dfn[N],low[N],tcnt,vis2[N],tmp[N],ct;
vector<int>ans[N];
void tarjan(int u){
dfn[u]=low[u]=++tcnt;
for(int v=1;v<=n;v++){
if(!e[u][v])continue;
if(!dfn[v]){
tarjan(v),low[u]=min(low[u],low[v]);
if(low[v]>=dfn[u]&&u!=p)vis[u]=1;
}
else low[u]=min(low[u],dfn[v]);
}
}
void dfs(int u){
vis2[u]=1;
for(int i=1;i<=ct;i++)ans[u].push_back(tmp[i]);
sort(ans[u].begin(),ans[u].end());
if(vis[u]){
tmp[++ct]=u;
for(int v=1;v<=n;v++){
if(!e[u][v]||vis2[v]||low[v]<dfn[u])continue;
dfs(v);
}
ct--;
}
for(int v=1;v<=n;v++){
if(!e[u][v]||vis2[v])continue;
dfs(v);
}
}
int main(){
cin>>n>>p;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++)scanf("%1d",&e[i][j]);
}
tarjan(p);
dfs(p);
for(int i=1;i<=n;i++){
if(i==p)continue;
if(ans[i].size()){
for(auto j:ans[i])printf("%d ",j);
printf("\n");
}else printf("No\n");
}
}
WA 求调