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[4100000];int len,last[1100000];
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[1100000],low[1100000];
bool b[1100000];
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]==0){tarjan(y,x);low[x]=min(low[x],low[y]);if(dfn[x]<low[y])b[k]=b[k^1]=true;}if(y!=fr)low[x]=min(low[x],dfn[y]);}
}
int cnt,bel[1100000];
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]==0&&b[k]==false)sdfj(y,x);}
}//--------------------缩点----------------------int Bin[25];
int f[25][1100000],dep[1100000];
void dfs(int x)
{for(int i=1;dep[x]>=Bin[i];i++)f[i][x]=f[i-1][f[i-1][x]];for(int k=last[x];k;k=a[k].next){int y=a[k].y;if(y!=f[0][x]){f[0][y]=x;dep[y]=dep[x]+1;dfs(y);}}
}
int LCA(int x,int y)
{if(dep[x]<dep[y])swap(x,y);for(int i=22;i>=0;i--)if(dep[x]-dep[y]>=Bin[i])x=f[i][x];if(x==y)return x;for(int i=22;i>=0;i--)if(dep[x]>=Bin[i]&&f[i][x]!=f[i][y])x=f[i][x],y=f[i][y];return f[0][x];
}//--------------get_LCA---------------------------- int fa[1100000];bool v[1100000];
int main()
{int n,m,T_T=0;while(scanf("%d%d",&n,&m)!=EOF){if(n==0&&m==0)break;printf("Case %d:\n",++T_T);len=1;memset(last,0,sizeof(last));int x,y;for(int i=1;i<=m;i++){scanf("%d%d",&x,&y);ins(x,y);ins(y,x);}z=0;memset(dfn,0,sizeof(dfn));memset(low,0,sizeof(low));memset(b,false,sizeof(b));tarjan(1,0);cnt=0;memset(bel,0,sizeof(bel));for(int i=1;i<=n;i++)if(bel[i]==0) cnt++, sdfj(i,0);int tp=0;memset(last,0,sizeof(last));for(int i=1;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[0]=1;for(int i=1;i<=22;i++)Bin[i]=Bin[i-1]*2;f[0][1]=0;dep[1]=0;dfs(1);for(int i=1;i<=cnt;i++)fa[i]=f[0][i];memset(v,false,sizeof(v));int Q,ans=cnt-1;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 0;
}

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[1100000];int len,last[1100];
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[1100];
bool col[1100],v[1100];
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]^1;if(findodd(y))return true;}else if(col[y]==col[x])return true;}}return false;
}
int z,dfn[1100],low[1100];
int top,sta[1100],hlen,h[1100]; bool inodd[1100];
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]==0){v_DCC(y,x);low[x]=min(low[x],low[y]);if(dfn[x]<=low[y]){int k;tim++;hlen=0;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]=0;if(findodd(y)){for(int i=1;i<=hlen;i++)inodd[h[i]]=true;}}}else if(y!=fr)low[x]=min(low[x],dfn[y]);}
}bool mp[1100][1100];
int main()
{int n,m,x,y;while(scanf("%d%d",&n,&m)!=EOF){if(n==0&&m==0)break;memset(mp,true,sizeof(mp));for(int i=1;i<=m;i++){scanf("%d%d",&x,&y);mp[x][y]=mp[y][x]=false;}len=0;memset(last,0,sizeof(last));for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)if(i!=j&&mp[i][j]==true)ins(i,j);z=0;top=0;tim=0;memset(dfn,0,sizeof(dfn));memset(low,0,sizeof(low));memset(inodd,false,sizeof(inodd));memset(ti,0,sizeof(ti));for(int i=1;i<=n;i++)if(dfn[i]==0)v_DCC(i,0);int ans=0;for(int i=1;i<=n;i++)if(inodd[i]==false)ans++;printf("%d\n",ans);}return 0;
}

poj2942

poj2230 欧拉回路裸题。

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

poj2230

转载于:https://www.cnblogs.com/AKCqhzdy/p/9540239.html

0x66 Tarjan算法与无向图联通性相关推荐

  1. 0x66.图论 - Tarjan算法与无向图连通性

    目录 一.无向图的割点与桥 割点 桥/割边 时间戳 搜索树 追溯值 二.割边判定法则 三.割点判定法则 1.luogu P3388 [模板]割点(割顶) 2.luogu P3469 [POI2008] ...

  2. C++算法篇:DFS超详细解析(2)--- tarjan算法求无向图割边

    <<<上一篇 系列文章目录 ①:无向图基本概念 ②:tarjan算法求无向图割边 前言 第一次写算法,讲得肯不透彻,有误还请指教awa 文章目录 系列文章目录 一.回顾 二.tarj ...

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

    tarjan算法求无向图的割点与桥 一篇tarjan算法求割点与桥的完整的解释,写的真的好认真 以下代码来自kuangbin的模板 4.5 图的割点.桥和双连通分支的基本概念 [点连通度与边连通度] ...

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

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

  5. Tarjan算法求无向图割边割点、最近公共祖先的总结

     无向图tarjan求割边割点.最近公共祖先总结 割点:删除这个点之后整个图变成不连通的两个部分的点 割点集合:在一个无向图中删除该集合中的所有点,能使原图变成互不相连的连通块的点的集合 点连通度 ...

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

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

  7. 『Tarjan算法 无向图的双联通分量』

    无向图的双连通分量 定义:若一张无向连通图不存在割点,则称它为"点双连通图".若一张无向连通图不存在割边,则称它为"边双连通图". 无向图图的极大点双连通子图被 ...

  8. POJ 2117 Electricity 割点 Tarjan算法

    [题意] 选择去掉无向图中的某个点,使得无向图连通分支数最大,输出这个最大数. 有三种情况: 1.无向图无边时,最大数=点数-1: 2.无向图有边并不存在割点时,最大数=原图连通分支数-1 3.无向图 ...

  9. c语言tarjan算法,无向图求割点和割边——Tarjan算法

    无向图中求割点集和割边集--Tarjan算法 割点和割边 定义 在一个无向图中,如果删除了某个顶点及与之相连的所有边,产生了一更大连通分量的子图,这样的顶点被称为割点或关节点.对于一个图的所有割点的集 ...

最新文章

  1. 别踩白块java程序代码_别踩白块源码
  2. 【Python】数据提取xpath和lxml模块(豆瓣电影排行榜的爬虫)
  3. 表单重复提交的解决方法
  4. 视频质量评估的新方式:VMAF百分位数
  5. Hibernate基础
  6. 动手学习_动手选择值
  7. webstorm使用技巧
  8. 张家口市12320卫生热线呼叫中心预计今年初启动
  9. 全球嵌入式技术与 IoT 产业回顾与展望 | 技术头条
  10. python如何将数据生成excel_python的将数据生成excel功能
  11. Linux配置自建 YUM 软件存储库
  12. python 分隔符截取字符串_Python重新分割()保留分隔符的一部分作为第一个字符串的一部分,另一部分作为第二个字符串的一部分,...
  13. 文字版--九九乘法表 c语言
  14. 二次开发—Ribbon界面
  15. 图像坐标球面投影_晶体的球面坐标与球面投影
  16. wishbone bus
  17. 【Windows Server 2019】路由服务的配置和管理
  18. 计算机培训结业典礼主持词,培训结业典礼主持词范文(一)
  19. 代码库_单精度浮点减法器
  20. CAD软件中怎么管理设备CAD图层?

热门文章

  1. 阿翔编程学-Castor
  2. 计算机控制实验PID数字控制器设计,实验二数字PID控制器的设计
  3. arcgis for js通过框架配置实现点线面及echarts绘制
  4. 【C++STL】deque的结构和使用
  5. Java代码通过Kerberos连接HDFS
  6. LocalSolver-全领域、超大规模混合变量数学规划介绍
  7. 投资20亿 宁波大数据云基地揭牌
  8. yolov5代码详解-compute_loss(p, targets, model)
  9. 9-5日度小满金融Java研发工程师笔试
  10. Microsoft Visual C++ 2005 SP1安装