Joe2011 @ 2024-09-15 20:42:11
题意简述:求无向图上两点间的必经边数量
我的代码:
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10,M=20,L=18;
int n,m,q,rt,idx,dfn[N],low[N],dep[N],fa[N][M];
vector<int> g[N],G[N];
stack<int> st;
map<pair<int,int>,int> mp;
void tarjan(int u,int pr){
low[u]=dfn[u]=++idx;
st.push(u);
bool flg=0;
for (int v:g[u]){
if (v==pr&&!flg){
flg=1;
continue;
}
if (dfn[v])
low[u]=min(low[v],dfn[v]);
else
tarjan(v,u),
low[u]=min(low[u],low[v]);
}
if (low[u]==dfn[u]){
int v;
do{
v=st.top();
st.pop();
}while (v!=u);
}
}
void dfs(int u,int pr){
fa[u][0]=pr;
dep[u]=dep[pr]+1;
for (int v:G[u]) if (v!=pr)
dfs(v,u);
}
int lca(int u,int v){
if (dep[v]>dep[u]) swap(u,v);
for (int i=L;i>=0;i--) if (dep[fa[u][i]]>=dep[v]) u=fa[u][i];
if (u==v) return u;
for (int i=L;i>=0;i--) if (fa[u][i]!=fa[v][i]) u=fa[u][i],v=fa[v][i];
return fa[u][0];
}
int main(){
cin>>n>>m;
for (int i=1;i<=m;i++){
int u,v;cin>>u>>v;
g[u].push_back(v);
g[v].push_back(u);
}
tarjan(1,0);
for (int i=1;i<=n;i++) for (int v:g[i]){
int x=low[i],y=low[v];
if (x!=y&&!mp[{x,y}])
G[x].push_back(y),
mp[{x,y}]=1;
}
dfs(low[1],0);
for (int i=1;i<=n;i++) if (low[i]==i)
for (int j=1;j<=L;j++)
fa[i][j]=fa[fa[i][j-1]][j-1];
cin>>q;
while (q--){
int a,b;
cin>>a>>b;
a=low[a],b=low[b];
cout<<dep[a]+dep[b]-2*dep[lca(a,b)]<<'\n';
}
return 0;
}
然后MLE+TLE+TLE+TLE。。。
by LH_Kenneth @ 2024-09-15 20:58:25
万能头文件很占内存
by Joe2011 @ 2024-09-15 21:21:45
@LH_Kenneth 6,我试试看
by Joe2011 @ 2024-09-15 21:22:49
@LH_Kenneth 好了一点,但还是MLE。。。
by LH_Kenneth @ 2024-09-15 21:28:50
666
by chrispang @ 2024-09-16 13:58:40
<<橙名蓝勾被绿名无勾点评了>>
by Joe2011 @ 2024-09-23 22:07:20
@chrispang 这个很正常,必竞我很菜