显然我们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
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#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]
你可能感兴趣的:(树,LCA,图论)