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 ...
随机推荐
- Yarn调度器负载模拟器——Yarn Scheduler Load Simulator (SLS)
一.概述: Yarn调度器有很多实现,如Fifo, Capacity和Fair schedulers等.与其同一时候,正在进行一些优化措施来提高调度器在不同负载和工作场景下的性能.每一个调度器都有自己 ...
- 编译异常之static和extern---more than one storage class specified
static 和 extern 不能同时共存 http://bbs.bccn.net/thread-58129-1-1.html
- C语言socket send()数据缓存问题
send()函数默认情况下会使用Nagle算法.Nagle算法通过将未确认的数据存入缓冲区直到积攒到一定数量一起发送的方法.来降低主机发送零碎小数据包的数目.所以假设send()函数发送数据过快的话, ...
- 简说 call() 、apply() 、bind()
对于这三个方法,我想一部分人还是比较陌生的. 所以今天来个简单的介绍~ 我们可以将call()和apply()看作是某个对象的方法,通过调用方法的形式来间接调用函数.call()和apply()的第一 ...
- 无线网络中的MAC协议(1)
前文我们对传统的有线网络的MAC协议进行了分析,接下来我们在对无线网络的MAC也进行一个详细的介绍.那么无线网络中的MAC工作方式是如何的呢?无线局域网(WLAN)中MAC所对应的标准为IEEE 80 ...
- codeforces 437B. The Child and Set 解题报告
题目链接:http://codeforces.com/contest/437/problem/B 题目意思:给出两个整数 sum 和 limit,问能否从1 - limit 这些数中选出一些数(注意: ...
- 一步一步学Silverlight 2系列文章
概述 由TerryLee编写的<Silverlight 2完美征程>一书,已经上市,在该系列文章的基础上补充了大量的内容,敬请关注.官方网站:http://www.dotneteye.cn ...
- 「UVA524」 Prime Ring Problem 质数环
Description 输入正整数n,把整数1,2,-,n组成一个环,使得相邻两个整数之和均为素数.输出时,从整数1开始逆时针排列.同一个环恰好输出一次.n<=16. A ring is com ...
- javascript之数组的6种去重方法
去重 var arr=[11,11,333,4,4,5,66,66,7]; // 方法一:在新数组内判断不存在时加入 var newarr1=[]; function quchong1(){ for( ...
- node mkdirSync 创建多级目录
提供一个实用的一次性同步创建多级目录的方法,收藏一下. function makeDir(dirpath) { if (!fs.existsSync(dirpath)) { var pathtmp; ...