显然我们Tarjan桥边然后爆搞LCA。。。等等!这不是O(nq)的吗?嗯。。。。。799ms= =
每次缩点复杂度。。。不会证啊= =
我们还是考虑树剖吧,先Tarjan,然后缩点,这成为了一个树,乱搞LCA,然后我们维护重链的答案,维护清空标记,显然这就是一个裸的树剖。
这样复杂度就是O(qlognlogn)的了,这样才对嘛
然而已经成为了一个退役狗还是不在熄灯之前折腾自己了,有空再补代码。前面检查Tarjan的时候过掉了代码就贴一贴把
/* *********************************************** Author :BPM136 Created Time :2016-5-3 20:36:54 File Name :A.cpp ************************************************ */ #include<iostream> #include<cstdio> #include<algorithm> #include<cstdlib> #include<cmath> #include<cstring> #include<utility> #include<functional> #include<numeric> #include<memory> #include<iterator> #define LL long long #define DB double #define LB long double #define UL unsigned long #define ULL unsigned long long #define pb push_back #define popb pop_back #define get(a,i) a&(1<<(i-1)) #define PAU putchar(32) #define ENT putchar(10) #define clr(a,b) memset(a,b,sizeof(a)) #define fo(_i,_a,_b) for(int _i=_a;_i<=_b;_i++) #define fd(_i,_a,_b) for(int _i=_a;_i>=_b;_i--) #define efo(_i,_a) for(int _i=last[_a];_i!=0;_i=e[_i].next) #define file(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout); #define mkd(x) freopen(#x".in","w",stdout); #define setlargestack(x) int size=x<<20;char *p=(char*)malloc(size)+size;__asm__("movl %0, %%esp\n" :: "r"(p)); #define end system("pause") using namespace std; LL read() { LL f=1,d=0;char s=getchar(); while (s<48||s>57){if (s==45) f=-1;s=getchar();} while (s>=48&&s<=57){d=d*10+s-48;s=getchar();} return f*d; } LL readln() { LL f=1,d=0;char s=getchar(); while (s<48||s>57){if (s==45) f=-1;s=getchar();} while (s>=48&&s<=57){d=d*10+s-48;s=getchar();} while (s!=10) s=getchar(); return f*d; } inline void write(LL x) { if(x==0){putchar(48);return;}if(x<0)putchar(45),x=-x; int len=0,buf[20];while(x)buf[len++]=x%10,x/=10; for(int i=len-1;i>=0;i--)putchar(buf[i]+48);return; } inline void writeln(LL x){write(x);ENT;} const int N = 100005; const int M = 200005; struct edge { int y,next; }e[M*2]; int last[N],ne; int dfn[N],Dfn[N],low[N],mark[N]; int n,m; int fa[N]; int index,ans; void add(int x,int y) { e[++ne].y=y;e[ne].next=last[x];last[x]=ne; } void add2(int x,int y) { add(x,y); add(y,x); } void init() { memset(last,0,sizeof(last)); ne=1; memset(Dfn,0,sizeof(Dfn)); memset(dfn,0,sizeof(dfn)); memset(low,0,sizeof(low)); memset(mark,0,sizeof(mark)); memset(fa,0,sizeof(fa)); index=0; ans=0; fo(i,1,m) { int x=read(),y=read(); add2(x,y); } } void Tarjan(int x) { dfn[x]=low[x]=++index; Dfn[x]=Dfn[fa[x]]+1; efo(i,x) { int y=e[i].y; if(!dfn[y]) { fa[y]=x; Tarjan(y); low[x]=min(low[x],low[y]); if(low[y]>dfn[x]) { ans++; mark[y]=1; } } else { if(y!=fa[x]) low[x]=min(low[x],dfn[y]); } } } void LCA(int x,int y) { while(Dfn[x]>Dfn[y]) { if(mark[x]) ans--,mark[x]--; x=fa[x]; } while(Dfn[x]<Dfn[y]) { if(mark[y]) ans--,mark[y]--; y=fa[y]; } while(x!=y) { if(mark[x]) ans--,mark[x]--; if(mark[y]) ans--,mark[y]--; x=fa[x], y=fa[y]; } } void work() { Tarjan(1); int T=read(); while(T--) { int x=read(),y=read(); LCA(x,y); writeln(ans); } ENT; } int main() { file(A); int T = 0; while(scanf("%d%d",&n,&m)!=EOF) { if(n==0&&m==0) return 0; printf("Case %d:\n",++T); init(); work(); } return 0; }