bzoj1123: [POI2008]BLO

poj3694 先e-DCC缩点,此时图就变成了树,树上每一条边都是桥。对于添加边的操作,相当于和树上一条路径构环,导致该路径上所有边都不成为桥。那么找这条新加边的最近公共祖先,把路径上的所有没被删掉的桥的数量计算出来,未操作之前桥的个数减去该值就是当前答案。中间因为一条边会多次删除,没有意义,可以采取并查集路径压缩的思想,直接指向下一个没有被删的桥

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std; struct node
{
int x,y,next;
}a[];int len,last[];
void ins(int x,int y)
{
len++;
a[len].x=x;a[len].y=y;
a[len].next=last[x];last[x]=len;
}
int z,dfn[],low[];
bool b[];
void tarjan(int x,int fr)
{
dfn[x]=low[x]=++z;
for(int k=last[x];k;k=a[k].next)
{
int y=a[k].y;
if(dfn[y]==)
{
tarjan(y,x);
low[x]=min(low[x],low[y]); if(dfn[x]<low[y])
b[k]=b[k^]=true;
}
if(y!=fr)
low[x]=min(low[x],dfn[y]);
}
}
int cnt,bel[];
void sdfj(int x,int fr)
{
bel[x]=cnt;
for(int k=last[x];k;k=a[k].next)
{
int y=a[k].y;
if(bel[y]==&&b[k]==false)
sdfj(y,x);
}
} //--------------------缩点---------------------- int Bin[];
int f[][],dep[];
void dfs(int x)
{
for(int i=;dep[x]>=Bin[i];i++)f[i][x]=f[i-][f[i-][x]]; for(int k=last[x];k;k=a[k].next)
{
int y=a[k].y;
if(y!=f[][x])
{
f[][y]=x;
dep[y]=dep[x]+;
dfs(y);
}
}
}
int LCA(int x,int y)
{
if(dep[x]<dep[y])swap(x,y);
for(int i=;i>=;i--)
if(dep[x]-dep[y]>=Bin[i])x=f[i][x];
if(x==y)return x;
for(int i=;i>=;i--)
if(dep[x]>=Bin[i]&&f[i][x]!=f[i][y])x=f[i][x],y=f[i][y];
return f[][x];
} //--------------get_LCA---------------------------- int fa[];bool v[];
int main()
{
int n,m,T_T=;
while(scanf("%d%d",&n,&m)!=EOF)
{
if(n==&&m==)break; printf("Case %d:\n",++T_T);
len=;memset(last,,sizeof(last));
int x,y;
for(int i=;i<=m;i++)
{
scanf("%d%d",&x,&y);
ins(x,y);ins(y,x);
}
z=;
memset(dfn,,sizeof(dfn));
memset(low,,sizeof(low));
memset(b,false,sizeof(b));
tarjan(,); cnt=;
memset(bel,,sizeof(bel));
for(int i=;i<=n;i++)
if(bel[i]==) cnt++, sdfj(i,);
int tp=;
memset(last,,sizeof(last));
for(int i=;i<=len;i++)
{
if(bel[a[i].x]!=bel[a[i].y])
{
tp++;
a[tp].x=bel[a[i].x];
a[tp].y=bel[a[i].y];
a[tp].next=last[a[tp].x];
last[a[tp].x]=tp;
}
}
len=tp; Bin[]=;for(int i=;i<=;i++)Bin[i]=Bin[i-]*;
f[][]=;dep[]=;dfs(); for(int i=;i<=cnt;i++)fa[i]=f[][i];
memset(v,false,sizeof(v));
int Q,ans=cnt-;
scanf("%d",&Q);
while(Q--)
{
scanf("%d%d",&x,&y);x=bel[x],y=bel[y];
int lca=LCA(x,y),t;
while(dep[x]>dep[lca])
{
if(v[x]==false){ans--;v[x]=true;}
t=fa[x];
if(dep[fa[x]]<dep[lca])fa[x]=lca;
x=t;
}
while(dep[y]>dep[lca])
{
if(v[y]==false){ans--;v[y]=true;}
t=fa[y];
if(dep[fa[y]]<dep[lca])fa[y]=lca;
y=t;
}
printf("%d\n",ans);
}
printf("\n");
}
return ;
}

poj3694

poj2942 建补图,也就是可以坐在一起的连边。对于一次会议,上面坐着的骑士在图中就是一个简单环,所以这道题其实就是找那些没有在任何奇环中的点。找出所有的v-DCC,用黑白染色判即可。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std; struct node
{
int x,y,next;
}a[];int len,last[];
void ins(int x,int y)
{
len++;
a[len].x=x;a[len].y=y;
a[len].next=last[x];last[x]=len;
} int tim,ti[];
bool col[],v[];
bool findodd(int x)
{
for(int k=last[x];k;k=a[k].next)
{
int y=a[k].y;
if(ti[y]==tim)
{
if(v[y]==false)
{
v[y]=true;
col[y]=col[x]^;
if(findodd(y))return true;
}
else if(col[y]==col[x])return true;
}
}
return false;
}
int z,dfn[],low[];
int top,sta[],hlen,h[]; bool inodd[];
void v_DCC(int x,int fr)
{
dfn[x]=low[x]=++z;sta[++top]=x;
for(int k=last[x];k;k=a[k].next)
{
int y=a[k].y;
if(dfn[y]==)
{
v_DCC(y,x);
low[x]=min(low[x],low[y]);
if(dfn[x]<=low[y])
{
int k;tim++;hlen=;
do
{
k=sta[top];top--;
h[++hlen]=k;
ti[k]=tim;v[k]=false;
}while(k!=y); if(dfn[x]==low[y])
{
h[++hlen]=x;
ti[x]=tim;v[x]=false;
}
col[y]=;
if(findodd(y))
{
for(int i=;i<=hlen;i++)
inodd[h[i]]=true;
}
}
}
else if(y!=fr)
low[x]=min(low[x],dfn[y]);
}
} bool mp[][];
int main()
{
int n,m,x,y;
while(scanf("%d%d",&n,&m)!=EOF)
{
if(n==&&m==)break; memset(mp,true,sizeof(mp));
for(int i=;i<=m;i++)
{
scanf("%d%d",&x,&y);
mp[x][y]=mp[y][x]=false;
}
len=;memset(last,,sizeof(last));
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
if(i!=j&&mp[i][j]==true)ins(i,j); z=;top=;tim=;
memset(dfn,,sizeof(dfn));
memset(low,,sizeof(low));
memset(inodd,false,sizeof(inodd));
memset(ti,,sizeof(ti));
for(int i=;i<=n;i++)
if(dfn[i]==)v_DCC(i,); int ans=;
for(int i=;i<=n;i++)
if(inodd[i]==false)ans++;
printf("%d\n",ans);
}
return ;
}

poj2942

poj2230 欧拉回路裸题。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std; struct node
{
int x,y,next;
}a[];int len,last[];
void ins(int x,int y)
{
len++;
a[len].x=x;a[len].y=y;
a[len].next=last[x];last[x]=len;
} int top,sta[],cur[]; bool v[];
int aslen,as[];
void euler()
{
top=;sta[++top]=;
memset(v,false,sizeof(v));
memcpy(cur,last,sizeof(cur));
while(top!=)
{
int x=sta[top],k;
for(k=cur[x];k&&v[k];k=a[k].next);
if(k)
{
sta[++top]=a[k].y;
v[k]=true;
cur[x]=a[k].next;
}
else top--,as[++aslen]=x;
}
}
int main()
{
int n,m,x,y;
scanf("%d%d",&n,&m);
len=;memset(last,,sizeof(last));
for(int i=;i<=m;i++)
{
scanf("%d%d",&x,&y);
ins(x,y);ins(y,x);
}
euler();
for(int i=aslen;i>=;i--)printf("%d\n",as[i]);
return ;
}

poj2230

0x66 Tarjan算法与无向图联通性的更多相关文章

  1. 0x66 Tarjan算法与无向图连通性(1)

    ……是什么? 给定无向连通图G=(V,E)(不一定连通); 割点:若对于x∈V,从图中删去节点x以及所有与x关联的边后,G分裂成两个或两个以上不相连的子图,则称x为G的割点. 桥(割边):若对于e∈E ...

  2. [Tarjan系列] Tarjan算法求无向图的双连通分量

    这篇介绍如何用Tarjan算法求Double Connected Component,即双连通分量. 双联通分量包括点双连通分量v-DCC和边连通分量e-DCC. 若一张无向连通图不存在割点,则称它为 ...

  3. tarjan算法求无向图的桥、边双连通分量并缩点

    // tarjan算法求无向图的桥.边双连通分量并缩点 #include<iostream> #include<cstdio> #include<cstring> ...

  4. tarjan算法--求无向图的割点和桥

    一.基本概念 1.桥:是存在于无向图中的这样的一条边,如果去掉这一条边,那么整张无向图会分为两部分,这样的一条边称为桥无向连通图中,如果删除某边后,图变成不连通,则称该边为桥. 2.割点:无向连通图中 ...

  5. tarjan算法--求解无向图的割点和桥

    1.桥:是存在于无向图中的这样的一条边,如果去掉这一条边,那么整张无向图会分为两部分,这样的一条边称为桥 也就是说 无向连通图中,如果删除某边后,图变成不连通,则称该边为桥 2.割点:无向连通图中,如 ...

  6. tarjan算法与无向图的连通性(割点,桥,双连通分量,缩点)

    基本概念 给定无向连通图G = (V, E)割点:对于x∈V,从图中删去节点x以及所有与x关联的边之后,G分裂为两个或两个以上不相连的子图,则称x为割点割边(桥)若对于e∈E,从图中删去边e之后,G分 ...

  7. Light OJ - 1026 - Critical Links(图论-Tarjan算法求无向图的桥数) - 带详细注释

     原题链接   无向连通图中,如果删除某边后,图变成不连通,则称该边为桥. 也可以先用Tajan()进行dfs算出所有点 的low和dfn值,并记录dfs过程中每个 点的父节点:然后再把所有点遍历一遍 ...

  8. [Tarjan系列] Tarjan算法求无向图的桥和割点

    RobertTarjan真的是一个传说级的大人物. 他发明的LCT,SplayTree这些数据结构真的给我带来了诸多便利,各种动态图论题都可以用LCT解决. 而且,Tarjan并不只发明了LCT,他对 ...

  9. SPF Tarjan算法求无向图割点(关节点)入门题

    SPF 题目抽象,给出一个连通图的一些边,求关节点.以及每个关节点分出的连通分量的个数 邻接矩阵只要16ms,而邻接表却要32ms,  花费了大量的时间在加边上. //   time  16ms 1 ...

随机推荐

  1. selenium有多个窗口时操作某个窗口的内容

    这个页面点击html/css后会弹出一个新的窗口,此时要操作新的窗口的内容,使用switchTo 跳转代码 driver.get("https://www.imooc.com"); ...

  2. 推荐几个好用的windows软件

    好久没上了,= = 之前用了一段MAC,感觉好用的地方就是 spotlight和触摸板,哈哈 然后在用回windows之后就找了一下,我之前有用Launchy这个软件,但是他是用来启动程序的,当然你也 ...

  3. String类面试坑题

    1.面试坑题F:\SHJT\JavaWorkspace\JavaSE\workspace\day13ezra\src\cn\itcast\sh\classcode\BTStringLastIndexO ...

  4. 安卓系统使用摄像头API

    原文链接:定制自己的安卓Camera        参考链接:http://blog.csdn.net/tankai19880619/article/details/9075839           ...

  5. 【sqli-labs】 less42 POST -Error based -String -Stacked(POST型基于错误的堆叠查询字符型注入)

    Forgot your password? New User click here? 看源码,可以发现和less 24不同的一点在于password字段没有进行转义处理 那就对password字段进行 ...

  6. XML-20100: (Fatal Error) Expected ';'. xml转word 导出时异常

    因为数据中包含特殊字符.需要进行转译. < < 小于号 > > 大于号 & & 和 &apos; ’ 单引号 " " 双引号 XML ...

  7. python自动发邮件库yagmail(转)

    一般发邮件方法 我以前在通过Python实现自动化邮件功能的时候是这样的: import smtplib from email.mime.text import MIMEText from email ...

  8. lvs直接路由模式DR模式

    1)实验所有关闭防火墙systemtcl stop firewalldsystemctl disable firewalldsetenforce 0iptables -F2)配置负载调度器配置虚拟IP ...

  9. vue-路由使用

    路由安装 终端下载路由插件 npm install vue-router --save-dev 配置 在main.js中引入插件 //Router 为自定义名 vue-router 为插件的名字 im ...

  10. eas之事件

    选择事件 选择事件是在选择块发生变化后发出.table.addKDTSelectListener(new KDTSelectListener(){    public void tableSelect ...