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. struts2OGNL表达式(三)

    OGNL表达式 OGNL对象试图导航语言.${user.addr.name}这种写法就叫对象试图导航.Struts框架使用OGNL作为默认的表达式语言 OGNL不仅仅可以试图导航,支持比EL表达式更加 ...

  2. BootStrap 资源包的下载和使用

    将附件中的包解压,放置webroot中,并在jsp页面中引用它们,即可以使用 bootstrap.rar (78.9 KB) 下载次数: 0

  3. Rabbit--ack机制

    消息应答时执行一个任务可能需要花费几秒钟,你可能会担心如果一个消费者在执行任务过程中挂掉了. 一旦RabbitMQ将消息分发给了消费者,就会从内存中删除.在这种情况下,如果正在执行任务的消费者宕机,会 ...

  4. MAVEN - 生命周期(1)

    三套生命周期:   MAVEN拥有三套互相独立的生命周期,分别是:clean.default和site. clean - 清理项目 default - 构建项目 site - 简历项目站点   这其中 ...

  5. Table is specified twice, both as a target for 'UPDATE' and as a separate source

    UPDATE Bins b SET b.ShopSn =’111201611111168706’ WHERE b.Id IN (SELECT b.Id FROM Bins b JOIN BinInve ...

  6. nodejs要远程连接另一个主机上的monogodb数据库服务器

    我的mongodb是装在linux下的. 首先,先添加用户 1.首先在mongodb服务器主机上进行terminal命令行,输入 mongo 2.输入 use admin 进入用户管理数据库 3.db ...

  7. Eclipse代码自动提示(内容辅助content assist)

    Eclipse中默认是输入"."后出现自动提示,用于类成员的自动提示,可是有时候我们希望它能在我们输入类的首字母后就出现自动提示,可以节省大量的输入时间(虽然按alt + /会出现 ...

  8. AMQP及RabbitMQ

    AMQPAMQP协议是一个高级抽象层消息通信协议,RabbitMQ是AMQP协议的实现.它主要包括以下组件: 1.Server(broker): 接受客户端连接,实现AMQP消息队列和路由功能的进程. ...

  9. ANN:DNN结构演进History—RNN

    前言: CNN在图像处理领域的极大成功源于CNN的二维递进映射结构,通过训练多层卷积核来进行特征提取函数训练,在二维图像的稀疏表达和语义关联分析方面有天生的结构优势.而涉及时序问题的逻辑序列分析-边长 ...

  10. javaee IO流复制的方法

    package Zjshuchu; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileN ...