https://vjudge.net/problem/HDU-3686

点双啊,就是在求割顶的时候,另外用一个栈来存一些

在遍历u点出发的边时,遇到树边或反向边(u,v)就把此边加入栈(可能要记一下边的编号)(但是,如果(u,v)是反过来看的反向边(此时dfn[v]>=dfn[u];实际反向边应该为(v,u))或者反过来的树边(此时k==(last^1))就不能加入)

遇到一个割点,就多一个点双(不考虑因为(fa<0&&child==1)的特判而去掉的割点)

计算(u,v)中遇到割点后,就不断从栈顶弹出边,直到栈顶的边与(u,v)相等,然后再弹出一个边;所有这些弹出的边以及边的两个端点都属于这个点双

先对原图求点双连通分量,求出每条边属于的点双

然后为原图中每一个点双新建一个点,向这个点双内每一个点连边,去掉原图所有边,得到一个新图(实际上是一棵树)

询问两条边a,b时,先找出它们属于的点双对应的点编号x,y,那么答案就是新树上x与y的最短路径中"非点双对应的点"的数量(由于实际是要求这两个点双在原图中的路径间割点数量,而只有割点才可能成为新树中要统计的点)

https://blog.csdn.net/u013480600/article/details/44835827

错误记录:

倍增写错。。。115行少d[anc[x][0]][0]

 #include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
#define fi first
#define se second
#define mp make_pair
#define pb push_back
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
#define CLR(x) memset(x,0,sizeof(x))
#define N 10100
#define M 101000
typedef pair<pii,int> ppi;
struct E{int to,nxt;};
namespace G
{
E e[M<<];
int f1[N],ne;
int dfn[N],bno[N],dfc,cnt,bn2[M];bool iscut[N];
ppi st[M];int top;
vector<int> bcc[N];
//#define D(x) ((x)&2147483646)
void clr()
{
CLR(f1);ne=;
CLR(dfn);CLR(bno);CLR(iscut);CLR(bn2);dfc=cnt=top=;
}
void me(int a,int b)
{
e[++ne].to=b;e[ne].nxt=f1[a];f1[a]=ne;
e[++ne].to=a;e[ne].nxt=f1[b];f1[b]=ne;
}
int dfs(int u,int last)
{
int k,v,lowu=dfn[u]=++dfc,chi=,lowv;ppi x;
for(k=f1[u];k;k=e[k].nxt)
{
v=e[k].to;
if(!dfn[v])
{
st[++top]=mp(mp(u,v),k);chi++;
lowv=dfs(v,k);lowu=min(lowu,lowv);
if(lowv>=dfn[u])
{
iscut[u]=;
cnt++;bcc[cnt].clear();
for(;;)
{
x=st[top--];
if(bno[x.fi.fi]!=cnt)
bno[x.fi.fi]=cnt,bcc[cnt].pb(x.fi.fi);
if(bno[x.fi.se]!=cnt)
bno[x.fi.se]=cnt,bcc[cnt].pb(x.fi.se);
bn2[x.se/]=cnt;
if(x.fi.fi==u&&x.fi.se==v) break;
}
}
}
else if(dfn[v]<dfn[u]&&k!=(last^))
{
st[++top]=mp(mp(u,v),k);
lowu=min(lowu,dfn[v]);
}
}
if(last<&&chi==) iscut[u]=;
return lowu;
}
}
int n,m,l2n=,qq;
namespace T
{
E e[N<<];
int f1[N<<],ne;
int anc[N<<][],d[N<<][],dep[N<<];
//d[i][j]表示i点到其2^j级祖先中(含i,不含祖先),共有几个圆点
bool vis[N<<];
void clr() {CLR(f1);CLR(anc);CLR(vis);CLR(d);CLR(dep);ne=;}
void me(int a,int b)
{
e[++ne].to=b;e[ne].nxt=f1[a];f1[a]=ne;
e[++ne].to=a;e[ne].nxt=f1[b];f1[b]=ne;
}
void dfs(int u,int fa)
{
int i;
vis[u]=;anc[u][]=fa;d[u][]=(u<=n);
for(i=;i<=l2n;i++)
{
anc[u][i]=anc[anc[u][i-]][i-];
d[u][i]=d[u][i-]+d[anc[u][i-]][i-];
}
for(int k=f1[u];k;k=e[k].nxt)
if(e[k].to!=fa)
{
dep[e[k].to]=dep[u]+;
dfs(e[k].to,u);
}
}
int ask(int x,int y)
{
int t,i,ans=;
if(dep[x]<dep[y]) swap(x,y);
for(t=dep[x]-dep[y],i=;t>;t>>=,i++)
if(t&) ans+=d[x][i],x=anc[x][i];
if(x==y) return ans;
for(i=l2n;i>=;i--)
if(anc[x][i]!=anc[y][i])
{
ans+=(d[x][i]+d[y][i]);
x=anc[x][i];y=anc[y][i];
}
ans+=(d[x][]+d[y][]+d[anc[x][]][]);
return ans;
}
}
int main()
{
int a,b,i,j;
while()
{
G::clr();T::clr();
scanf("%d%d",&n,&m);
if(n==&&m==) break;
for(i=;i<=m;i++) scanf("%d%d",&a,&b),G::me(a,b);
for(i=;i<=n;i++) if(!G::dfn[i]) G::dfs(i,-);
for(i=;i<=G::cnt;i++)
for(j=;j<G::bcc[i].size();j++)
T::me(n+i,G::bcc[i][j]);
for(i=;i<=n+G::cnt;i++)
if(!T::vis[i])
T::dfs(i,);
scanf("%d",&qq);
while(qq--)
{
scanf("%d%d",&a,&b);
printf("%d\n",T::ask(n+G::bn2[a],n+G::bn2[b]));
}
}
return ;
}

最新文章

  1. codeforces 580D:Kefa and Dishes
  2. 自然语言16_Chunking with NLTK
  3. windows cmd command line 命令
  4. 解决tableView分割线左边不到边的情况
  5. While readingiphone真机无法显示图片,而模拟器可以正常显示
  6. cas sso单点登录系列1_cas-client Filter源码解码(转)
  7. iconv any encoding to UTF-8
  8. smartforms换页,
  9. InnoDB锁
  10. Material Design之CoordinatorLayout+AppBarLayout实现上滑隐藏ToolBar
  11. 详解intellij idea搭建SSM框架(spring+maven+mybatis+mysql+junit)(上)
  12. Mariadb第一章:介绍及安装--小白博客
  13. 软件工程——四则运算py(我小学的时候怎么没用过这东西?)
  14. EF 事务(转载)
  15. bzoj3209 花神的数论题——数位dp
  16. 用于模型选择的AIC与BIC
  17. Selenium 查找节点
  18. 审计系统---paramiko模块学习
  19. hdoj1160 FatMouse&#39;s Speed 动态规划
  20. 基于Cocos2d-x学习OpenGL ES 2.0系列——OpenGL ES渲染之Shader准备(7)

热门文章

  1. C++游戏系列2:角色装备武器
  2. 答案{{index==0 ? &#39;一&#39; : (index==1 ? &#39;二&#39;:&#39;三&#39; )}}
  3. 如何在退出Hue后关闭Spark会话
  4. Tomcat的虚拟主机的配置
  5. e.target与e.currentTarget的区别
  6. 一步一步学Silverlight 2系列(21):如何在Silverlight中调用JavaScript
  7. 后台while收发过程
  8. [原创]java合并word文件
  9. SPOJ:Collecting Candies(不错的DP)
  10. 如何给lemon开无限栈