思路:tarjan把桥找出来,然后缩点,注意这里的缩点是:如果两个点之间的连边不是桥,那么就把他们缩起来,然后用一个lct维护,对于每个询问,如果官道连接的是两个联通块的话,就把他们连起来,否则我们就把u到v的路径全部染色成0

最后只要询问缩点完的S到缩点完的T的路径上有多少是1就是答案了,最后复杂度:O(nlogn)

至于为什么这么做:因为我们要找必经过的边,这不就是桥吗,那我们先预处理出原来图的桥,然后把图转变成树,之后对于官道来说,它只要是连接了两个在同一个联通块里的点,就表明这段路绝对不可能是必经之路,而对于连接两个连通分量的边,那么它就是新的桥啊!因此它要被新建成为lct中的一条边。

#include<cstdio>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<cstring>
struct edge{
int u,v;
}e[];
int n,m;
int tot,go[],next[],first[],Id[];
int ch[][],sz,num,sum[],w[],col[],tag[];
int dfn[],low[],pd[],vis[];
int st[],c[],belong[],fa[];
int rev[],size[];
int read(){
int t=,f=;char ch=getchar();
while (ch<''||ch>''){if (ch=='-')f=-;ch=getchar();}
while (''<=ch&&ch<=''){t=t*+ch-'';ch=getchar();}
return t*f;
}
void insert(int x,int y,int id){
tot++;
go[tot]=y;
next[tot]=first[x];
first[x]=tot;
Id[tot]=id;
}
void add(int x,int y,int id){
insert(x,y,id);
insert(y,x,id);
}
void tarjan(int x,int Fa){
dfn[x]=low[x]=++sz;
for (int i=first[x];i;i=next[i])
if (Id[i]!=Fa){
int pur=go[i];
if (!dfn[pur]){
tarjan(pur,Id[i]);
low[x]=std::min(low[x],low[pur]);
if (low[pur]>dfn[x]) pd[Id[i]]=;
}else{
low[x]=std::min(low[x],dfn[pur]);
}
}
}
void bfs(int x){
int h=,t=;c[]=x;vis[x]=;belong[x]=++num;
while (h<=t){
int now=c[h++];
for (int i=first[now];i;i=next[i]){
int pur=go[i];
if (pd[Id[i]]||vis[pur]) continue;
c[++t]=pur;
vis[pur]=;
belong[pur]=num;
}
}
}
bool isroot(int x){
return ch[fa[x]][]!=x&&ch[fa[x]][]!=x;
}
void pushdown(int x){
int l=ch[x][],r=ch[x][];
if (tag[x]!=){
int id=(tag[x]==)?:;
if (l)tag[l]=tag[x];
if (r)tag[r]=tag[x];
if (l&&w[l]) col[l]=id;
if (r&&w[r]) col[r]=id;
if (l) sum[l]=size[l]*id;
if (r) sum[r]=size[r]*id;
tag[x]=;
}
if (rev[x]){
rev[l]^=;
rev[r]^=;
rev[x]=;
std::swap(ch[x][],ch[x][]);
}
}
void updata(int x){
int l=ch[x][],r=ch[x][];
if (w[x]==){
col[x]=;sum[x]=;size[x]=;
if (l) sum[x]+=sum[l],size[x]+=size[l];
if (r) sum[x]+=sum[r],size[x]+=size[r];
return;
}
sum[x]=col[x];size[x]=;
if (l) sum[x]+=sum[l],size[x]+=size[l];
if (r) sum[x]+=sum[r],size[x]+=size[r];
}
void rotate(int x){
int y=fa[x],z=fa[y],l,r;
if (ch[y][]==x) l=;else l=;r=l^;
if (!isroot(y)){
if (ch[z][]==y) ch[z][]=x;else ch[z][]=x;
}
fa[x]=z;fa[y]=x;fa[ch[x][r]]=y;
ch[y][l]=ch[x][r];ch[x][r]=y;
updata(y);updata(x);
}
void splay(int x){
int top=;st[]=x;
for (int i=x;!isroot(i);i=fa[i])
st[++top]=fa[i];
for (int i=top;i;i--)
pushdown(st[i]);
while (!isroot(x)){
int y=fa[x],z=fa[y];
if (!isroot(y)){
if (ch[y][]==x^ch[z][]==y) rotate(x);
else rotate(y);
}
rotate(x);
}
//updata(x);
}
void access(int x){
for (int t=;x;t=x,x=fa[x]){
splay(x);
ch[x][]=t;
updata(x);
}
}
void makeroot(int x){
access(x);splay(x);rev[x]^=;
}
int find(int x){
access(x);splay(x);
while (ch[x][]) x=ch[x][];
return x;
}
void cut(int x,int y){
makeroot(x);access(y);splay(y);
ch[y][]=fa[ch[y][]]=;
updata(y);
}
void link(int x,int y){
makeroot(x);fa[x]=y;
}
int main(){
n=read();m=read();
for (int i=;i<=m;i++){
e[i].u=read();e[i].v=read();
add(e[i].u,e[i].v,i);
}
for (int i=;i<=n;i++)
if (!dfn[i]) tarjan(i,);
sz=;num=;
for (int i=;i<=n;i++)
if (!vis[i]) bfs(i);
sz=num;
for (int i=;i<=m;i++)
if (belong[e[i].u]!=belong[e[i].v]){
sz++;col[sz]=;tag[sz]=;sum[sz]=;w[sz]=;
size[sz]=;
link(sz,belong[e[i].u]);
link(sz,belong[e[i].v]);
}
int q=read();
while (q--){
int S=read(),T=read(),Num=read(),cnt=;
S=belong[S],T=belong[T];
for (int i=;i<=Num;i++){
e[i].u=read();e[i].v=read();
e[i].u=belong[e[i].u];
e[i].v=belong[e[i].v];
}
for (int i=;i<=Num;i++){
if (e[i].u==e[i].v) continue;
if (find(e[i].u)!=find(e[i].v)){
w[sz+i]=;sum[sz+i]=;
tag[sz+i]=;col[sz+i]=;
size[sz+i]=;
link(e[i].u,sz+i);
link(e[i].v,sz+i);
pd[i]=;
}else{
pd[i]=;
makeroot(e[i].u);access(e[i].v);splay(e[i].v);
tag[e[i].v]=;
}
}
if (find(S)!=find(T)){
puts("-1");
}else{
makeroot(S);access(T);splay(T);
printf("%d\n",sum[T]);
}
for (int i=Num;i>=;i--){
if (e[i].u==e[i].v) continue;
if (pd[i]==){
cut(e[i].u,sz+i);
cut(e[i].v,sz+i);
}else{
makeroot(e[i].u);access(e[i].v);splay(e[i].v);
tag[e[i].v]=-;
}
}
}
}

XJOI网上同步测试DAY14 T3的更多相关文章

  1. XJOI网上同步测试DAY14 T2

    思路:先考虑在D高度的最小圆覆盖,再一层一层往下走时,可以保证圆心与最开始的圆相同的时候答案是最优的. 时间复杂度O(n) 有一个坑点,就是我用了srand(time(NULL))就T了,RP太差了. ...

  2. XJOI网上同步测试DAY14 T1

    思路:线段树维护最短路 #include<cstdio> #include<cmath> #include<iostream> #include<algori ...

  3. XJOI网上同步训练DAY5 T3

    就是对于一个数,我们去考虑把t*****减到(t-1)9999*的代价. #include<cstdio> #include<cmath> #include<algori ...

  4. XJOI网上同步训练DAY1 T3

    思路:一开始看到这题的时候想DP,可是发现貌似不行..因为有前缀也有后缀,而且有的后缀会覆盖到现在的前缀,这就不满足无后效性了啊! 但是有个很巧妙的思路:如果我们知道a[i]的最大值,那么p的数量和q ...

  5. XJOI网上同步训练DAY6 T2

    思路:记得FJ省队集训好像有过这题,可是我太弱了,根本不懂T_T #include<cstdio> #include<iostream> #include<cmath&g ...

  6. XJOI网上同步训练DAY6 T1

    思路:考试的时候直接想出来了,又有点担心复杂度,不过还是打了,居然是直接A掉,开心啊. 我们发现,Ai<=7,这一定是很重要的条件,我们考虑状态压缩,去枚举路径中出现了哪些数字,然后我们把原来n ...

  7. XJOI网上同步训练DAY5 T1

    思路:考虑得出,最终的集合一定是gcd=1的集合,那么我们枚举n个数中哪个数必须选,然后把它质因数分解,由于质数不会超过9个,可以状态压缩,去得出状态为0的dp值就是答案. #include<c ...

  8. XJOI网上同步训练DAY3 T2

    考试的时候已经想出来怎么做了,但是没有时间打了T_T 思路:我们考虑将询问以lim排序,然后树链剖分,把边作为线段树的节点,然后随着询问lim的增大,改变线段树中节点的信息,然后每次询问我们用树链剖分 ...

  9. XJOI网上同步训练DAY3 T1

    思路:看来我真是思博了,这么简单的题目居然没想到,而且我对复杂度的判定也有点问题.. 首先我们选了一个位置i的b,那一定只对i和以后的位置造成改变,因此我们可以这样看: 我们从前往后选,发现一个位置的 ...

随机推荐

  1. java中集合杂记

    HashSet类按照哈希算法来存取集合中的对象,具有很有的性能.当HashSet向集合中加入一个对象时,会调用对象的hashCode()方法获得哈希码,然后根据这个哈希码进一步计算出对象在集合中的存放 ...

  2. Python自动化之Django的CSRF

    什么CSRF? CSRF, Cross Site Request Forgery, 跨站点伪造请求.举例来讲,某个恶意的网站上有一个指向你的网站的链接,如果 某个用户已经登录到你的网站上了,那么当这个 ...

  3. JavaScript实现自定义短信模板

    自定义短信模板,要求:可以插入关键字,当然是可以在点击到文本域中的任意位置,关键字以中括号包裹的形式出现[关键字],删除关键字要整个关键都删掉,而不是自己全删除. 详细在简书中 http://www. ...

  4. NGUI 动态字体边缘模糊,毛边的问题解决办法

    NGUI支持生成动态字体,将ttf格式的字体文件拖入工程,用NGUIFontMaker制作即可,但是制作完之后会发现字体有毛边,边缘模糊. 这时选中你生成的字体预设,在该预设的UIFont脚本上更改P ...

  5. Android 出现警告Exported service does not require permission

    在配置Android清单文件的时候,配置service,或者activity,或者receive的时候,出现Exported service does not require permission警告 ...

  6. RPM包校验和提取

    一.RPM包校验 [root@localhost Packages]# rpm -V 已安装的包名 #选项: #    -V    校验指定RPM包中的文件(verify) [root@localho ...

  7. Vitamio VideoView 示例

    VideoView 播放本地视频 /**  * 会根据视频尺寸自动缩放  * 自己对VideoView设置的宽高基本不起任何作用  */ public class VideoViewDemo exte ...

  8. sqlserver中的统计语法

    set statisitcs io {on | off} 显示与执行的sql语句有关的磁盘活动量的信息 set statistics profile {on | off} 显示语句的配置文件信息 se ...

  9. div中英文无法自动换行的解决办法

    在一个设定好宽度的div中,当我们输入的中文文字长度超过了设定宽度时,会自动换到下一行.   但是,如果输入的是英文字母,那么,无论你div设定宽度为多少,英文字母都是不换行直接在同一行输出,导致di ...

  10. 嵌套repeater

    通过外层repeater的值来进行内层repeater的数据绑定 前台代码部分: <asp:repeater runat="server" id="repeater ...