找出所有的割点然后把两个割点之间的所有边缩成一个点
于是变成了求路径上割点数目
然而炸了3天=生命不息=Tle不止
和wzf2000对拍跑的还比他快QAQ
这是老的RE程序==QAQ两天半啊
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define rep(j,k,l) for (int j=k;j<=l;++j)
#define red(j,k,l) for (int j=k;j>=l;--j)
#define min(a,b) (a)<(b)?(a):(b)
#define N 40009
#define M 400009
using namespace std;
int dfn[N],low[N],iscut[N],bbl[M],used[M],lnk[M][2],stk[M];
int st[N],to[M*2],ne[M*2],deep[N],bz[N][25],bl[N];
int n,m,cl,top,tme,cnt,Q;
int read(){
char ch=getchar();
while (ch<'0'||ch>'9') ch=getchar();
int k=ch-48;
while (1){
ch=getchar();
if (ch<'0'||ch>'9') return k;
k=k*10+ch-48;
}
}
void add(int k,int l){
to[++cnt]=l;
ne[cnt]=st[k];
st[k]=cnt;
to[++cnt]=k;
ne[cnt]=st[l];
st[l]=cnt;
}
void tj(int k){
dfn[k]=low[k]=++tme;
for (int i=st[k];i;i=ne[i]){
int ll=(i+1)/2;
if (used[ll]) continue;
stk[++top]=ll;
used[ll]=1;
if (k!=lnk[ll][0]) swap(lnk[ll][0],lnk[ll][1]);
int l=to[i];
if (dfn[l]==0){
tj(to[i]);
low[k]=min(low[k],low[l]);
if (low[l]>=dfn[k]){
int poi;
cl++;
iscut[k]++;
do{
bbl[stk[top]]=cl;
poi=lnk[stk[top--]][0];
}while (poi!=k);
}
}else low[k]=min(low[k],low[l]);
}
}
void dfs(int k,int fa,int lych){
deep[k]=deep[fa]+1;
bz[k][0]=fa;
bl[k]=lych;
for (int i=st[k];i;i=ne[i])
if (to[i]!=fa)
dfs(to[i],k,lych);
}
void init(){
rep(i,1,n) dfn[i]=low[i]=iscut[i]=st[i]=0;
rep(i,1,m) bbl[i]=used[i]=0,lnk[i][0]=read(),lnk[i][1]=read();
cnt=cl=tme=0;
rep(i,1,m) if (lnk[i][0]!=lnk[i][1]) add(lnk[i][0],lnk[i][1]);
else cnt+=2;
rep(i,1,n) if (dfn[i]==0) top=0,tj(i),iscut[i]--;
/* check *//*
rep(i,1,m) printf("%d ",bbl[i]);
printf("\n");
rep(i,1,n) printf("%d ",iscut[i]);
printf("\n");
*//* check */
rep(i,1,n) if (iscut[i]) iscut[i]=++cl;
rep(i,1,cl) st[i]=deep[i]=bl[i]=0;
n=cl;cl=0;cnt=0;
rep(i,1,m) if (lnk[i][0]!=lnk[i][1]){
if (iscut[lnk[i][0]]) add(bbl[i],iscut[lnk[i][0]]);
if (iscut[lnk[i][1]]) add(bbl[i],iscut[lnk[i][1]]);
}
rep(i,1,n) if (deep[i]==0){
cl++;
dfs(i,i,cl);
}
rep(i,1,23) rep(j,1,n)
bz[j][i]=bz[bz[j][i-1]][i-1];
}
int lca(int k,int l){
if (deep[k]<deep[l]) swap(k,l);
red(i,23,0) if (deep[k]-(1<<i)>=deep[l]) k=bz[k][i];
if (k==l) return k;
red(i,23,0) if (bz[k][i]!=bz[l][i])
k=bz[k][i],l=bz[l][i];
return bz[k][0];
}
void solve(){
Q=read();
while (Q--){
int k=read(),l=read();
k=bbl[k];l=bbl[l];
if (bl[k]!=bl[l]||!k||!l){
printf("0\n");
continue;
}
int p=lca(k,l);
printf("%d\n",(deep[k]+deep[l]-deep[p]*2)/2);
}
}
int main(){
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
while (scanf("%d%d",&n,&m)!=EOF&&n&&m){
init();
solve();
}
return 0;
}
这是重打的TLE程序QAQ=另一个两天半啊
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define rep(j,k,l) for (int j=k;j<=l;j++)
#define red(j,k,l) for (int j=k;j>=l;j--)
#define MST(a,b) memset(a,b,sizeof(a))
#define N 40005
#define M 400005
using namespace std;
struct _233{
int k,l,i;
} b[M];
int stk[M],deep[N],low[N],wlc[N][25],bl[M],pi[N],p[M];
int to[M*2],ne[M*2],dfn[N],ict[N],st[N],nm[M*2],fa[N];
int n,m,cnt,top,cl,tme;
bool used[M];
void add(int k,int l){
to[++cnt]=l;
ne[cnt]=st[k];
st[k]=cnt;
to[++cnt]=k;
ne[cnt]=st[l];
st[l]=cnt;
}
int read(){
char ch=getchar();
while (ch<'0'||ch>'9') ch=getchar();
int l=ch-48;
while (1){
ch=getchar();
if (ch<'0'||ch>'9') return l;
l=l*10+ch-48;
}
}
void tj(int k,int ff){
//printf("%d\n",k);
dfn[k]=low[k]=++tme;
for (int i=st[k];i;i=ne[i]) if (to[i]!=ff&&used[nm[i]]==0){
stk[++top]=nm[i];
used[nm[i]]=1;
if (b[nm[i]].k!=k)
swap(b[nm[i]].k,b[nm[i]].l);
if (dfn[to[i]]==0){
tj(to[i],k);
if (low[to[i]]>=dfn[k]){
ict[k]++;
cl++;
int poi;
do{
poi=stk[top--];
bl[poi]=cl;
//printf("---%d\n",poi);
}while (b[poi].k!=k);
}
}
low[k]=min(low[k],low[to[i]]);
}
}
void dfs(int k,int ff){
deep[k]=deep[ff]+1;
wlc[k][0]=ff;
pi[k]=tme;
fa[k]=ff;
for (int i=st[k];i;i=ne[i]) if (to[i]!=ff) dfs(to[i],k);
}
bool cmp(const _233 &x,const _233 &y){
if (x.k+x.l!=y.k+y.l) return x.k+x.l<y.k+y.l;
return min(x.k,x.l)<min(y.k,y.l);
}
void init(){
cnt=tme=cl=0;
MST(st,0);
MST(dfn,0);
MST(used,0);
MST(ict,0);
rep(i,1,m) b[i].k=read(),b[i].l=read(),b[i].i=i;
sort(b+1,b+m+1,cmp);
rep(i,1,m) p[b[i].i]=i;
rep(i,1,m) if (b[i].k!=b[i].l&&(i==1||(b[i].k+b[i].l!=b[i-1].k+b[i-1].l||(b[i].k!=b[i-1].k&&b[i].k!=b[i-1].l)))) add(b[i].k,b[i].l),nm[cnt]=nm[cnt-1]=i;
rep(i,1,n) if (dfn[i]==0) top=0,tj(i,i),ict[i]--;
rep(i,1,n) if (ict[i]) ict[i]=++cl;
//rep(i,1,n) printf("%d ",ict[i]);printf("\n");
//rep(i,1,m) printf("%d ",bl[i]);printf("\n");
cnt=tme=0;
MST(st,0);
MST(deep,0);
rep(i,1,m) if (b[i].k!=b[i].l&&(i==1||(b[i].k+b[i].l!=b[i-1].k+b[i-1].l||(b[i].k!=b[i-1].k&&b[i].k!=b[i-1].l)))){
if (ict[b[i].k]) add(ict[b[i].k],bl[i]);
//,printf("%d %d\n",ict[b[i].k],bl[i]);
if (ict[b[i].l]) add(ict[b[i].l],bl[i]);
//,printf("%d %d\n",ict[b[i].l],bl[i]);
}else if (b[i].k!=b[i].l) p[b[i].i]=p[b[i-1].i];
rep(i,1,cl) if (deep[i]==0) tme++,dfs(i,i);
rep(j,1,23) rep(i,1,cl) wlc[i][j]=wlc[wlc[i][j-1]][j-1];
}
int lca(int k,int l){
if (deep[k]<deep[l]) swap(k,l);
red(i,23,0) if (deep[l]+(1<<i)<=deep[k]) k=wlc[k][i];
if (k==l) return k;
red(i,23,0) if (wlc[k][i]!=wlc[l][i])
k=wlc[k][i],l=wlc[l][i];
return fa[k];
}
void solve(){
int T=read();
while (T--){
int k=bl[p[read()]],l=bl[p[read()]];
if (pi[k]!=pi[l]){
printf("0\n");
continue;
}
int p=lca(k,l);
printf("%d\n",(deep[k]+deep[l]-deep[p]*2)/2);
}
}
int main(){
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
while (scanf("%d%d",&n,&m),n&&m){
init();
solve();
}
//system("pause");
}
若看出我哪里炸了请告诉我=我已经弃疗了