Traffic Real Time Query System HDU - 3686
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 ;
}
Traffic Real Time Query System HDU - 3686的更多相关文章
- HDU 3686 Traffic Real Time Query System (图论)
HDU 3686 Traffic Real Time Query System 题目大意 给一个N个点M条边的无向图,然后有Q个询问X,Y,问第X边到第Y边必需要经过的点有多少个. solution ...
- CH#24C 逃不掉的路 和 HDU3686 Traffic Real Time Query System
逃不掉的路 CH Round #24 - 三体杯 Round #1 题目描述 现代社会,路是必不可少的.任意两个城镇都有路相连,而且往往不止一条.但有些路连年被各种XXOO,走着很不爽.按理说条条大路 ...
- HDU 3686 Traffic Real Time Query System(双连通分量缩点+LCA)(2010 Asia Hangzhou Regional Contest)
Problem Description City C is really a nightmare of all drivers for its traffic jams. To solve the t ...
- HDU3686 Traffic Real Time Query System 题解
题目 City C is really a nightmare of all drivers for its traffic jams. To solve the traffic problem, t ...
- Traffic Real Time Query System 圆方树+LCA
题目描述 City C is really a nightmare of all drivers for its traffic jams. To solve the traffic problem, ...
- hdu 3686 Traffic Real Time Query System 点双两通分量 + LCA。这题有重边!!!
http://acm.hdu.edu.cn/showproblem.php?pid=3686 我要把这题记录下来. 一直wa. 自己生成数据都是AC的.现在还是wa.留坑. 我感觉我现在倒下去床上就能 ...
- HDU 3686 Traffic Real Time Query System(点双连通)
题意 给定一张 \(n\) 个点 \(m\) 条边的无向图,\(q\) 次询问,每次询问两边之间的必经之点个数. 思路 求两点之间必经之边的个数用的是边双缩点,再求树上距离.而对比边双和点双之 ...
- HDU Traffic Real Time Query System
题目大意是:对于(n, m)的图,给定边a, b查询从a到b要经过的割点的最少数目. 先tarjan算法求双连通然后缩点,即对于每个割点将周围的每个双连通看成一个点与之相连.然后求解LCA即可,距离d ...
- 【HDOJ】3686 Traffic Real Time Query System
这题做了几个小时,基本思路肯定是求两点路径中的割点数目,思路是tarjan缩点,然后以割点和连通块作为新节点见图.转化为lca求解.结合点——双连通分量与LCA. /* 3686 */ #includ ...
随机推荐
- mysql limit分页优化方法分享
同样是取10条数据 select * from yanxue8_visit limit 10000,10 和 select * from yanxue8_visit limit 0,10 就不是 ...
- 二分法和牛顿迭代实现开根号函数:OC的实现
最近有人贴出BAT的面试题,题目链接. 就是实现系统的开根号的操作,并且要求一定的误差,其实这类题就是两种方法,二分法和牛顿迭代,现在用OC的方法实现如下: 第一:二分法实现 -(double)sqr ...
- xcode4中build Settings常见参数解析
本文转载至 http://shiminghua234.blog.163.com/blog/static/263912422012411103526386/ 1.Installation Dir ...
- 2016/06/16 phpexcel
程序部分 require_once './phpexcel/PHPExcel.php'; // 首先创建一个新的对象 PHPExcel object $objPHPExcel = new ...
- bash_action
https://stackoverflow.com/questions/12076326/how-to-install-maven2-on-redhat-linux #!/bin/bash # Tar ...
- HTML5 and Websocket
在HTML5规范中,我最喜欢的Web技术就是正迅速变得流行的WebSocket API.WebSocket提供了一个受欢迎的技术,以替代我们过去几年一直在用的Ajax技术.这个新的API提供了一个方法 ...
- jws webservice code
1.服务器端建立 1.1.创建接口 [java] view plaincopy @WebService public interface IWebService { int add(int ...
- if return 和 if else
最近看Node.js实战中,有一段代码是优化之前使用if else,优化之后是使用if return,我不知道if return是不是效率比if else高. 优化前: if(err){ handle ...
- 数据库DCL、DDL、DML、DQL
SQL三部分:data manipulation language DCL: (控制)管理用户权限(GRANT.REVOKE),数据库整体配置 DDL: (定义)作用于数据库,表, ...
- xalion三层与Web开发帖子一览表 good
使用http.sys,让delphi 的多层服务飞起来(Delphi借用http.sys充当http服务器,也就可以发送返回JSON等信息,当然浏览器也可以使用)http://www.cnblogs. ...