poj3694 连通图+LCA
来源:互联网 发布:单片机电路设计 编辑:程序博客网 时间:2024/05/01 02:12
不缩点,直接在原图中找LCA,求桥时记录每个节点的父亲节点
找LCA时,先将两点上升到同一层次,然后一起再向上找父亲节点,遇到桥就把桥标记删除,画一下图就清楚了
间遇到桥就把桥的标记删除,画一下图就清楚了
#include <iostream>#include<stdio.h>#include<cstring>#include<algorithm>#include<queue>#include<math.h>using namespace std;#define maxn 100010#define FOR(i,j,k) for(int i=j;i<=k;i++)struct edge{ int to,next;}edge[400010];int chu[maxn],ru[maxn];//强连通分量的出度,入度int dfn[maxn];//时间戳,该点最早发现时间int low[maxn];//该点及其后代能连回的最早祖先值int vis[maxn],stack[maxn],head[maxn];int belong[maxn];//每个点属于几号分量int fa[maxn];bool bridge[maxn];int n;int tot;//一共多少条边int cnt;//一共多少分量int ans;//一共多少桥int times,top;void init(){ tot=0,cnt=0,times=0,top=0,ans=0; memset(head,-1,sizeof(head)); memset(dfn,0,sizeof(dfn)); memset(low,0,sizeof(low)); // memset(belong,0,sizeof(belong)); // memset(chu,0,sizeof(chu)); // memset(ru,0,sizeof(ru)); memset(vis,0,sizeof(vis)); memset(stack,0,sizeof(stack)); memset(bridge,0,sizeof(bridge)); FOR(i , 1, n) fa[i] = i;}void addedge(int from,int to){ tot++; edge[tot].to=to; edge[tot].next=head[from]; head[from]=tot;}void tarjan(int u){ int v,i; times++; top++; dfn[u]=low[u]=times; vis[u]=1; stack[top]=u; for (i=head[u];i!=-1;i=edge[i].next) { v=edge[i].to; if( v== fa[u]) continue; if (vis[v]==0) //树边 { fa[v] =u; tarjan(v); low[u]=min(low[u],low[v]); if(low[v] >dfn[u] ) { ans ++; bridge[v] =true; } } if (vis[v]==1) low[u]=min(low[u],dfn[v]); } /*if (dfn[u] == low[u]) { cnt++; while(1) { v=stack[top]; belong[v]=cnt; vis[v]=2; top--; if(u == v) break; } }*/ vis[u]=2;}void lca(int u,int v){ if(dfn[u] > dfn[v]) swap( u, v); while( dfn[u] < dfn[v]) { if(bridge [v]) ans--,bridge[v]=0; v=fa[v]; } while( u != v) { if(bridge[u]) ans--,bridge[u]=0; if(bridge[v]) ans--,bridge[v]=0; u=fa[u],v=fa[v]; }}int main(){ int n,m,q; int cas=0; while(~scanf("%d%d",&n,&m)){ if (n==0 && m==0) break; cas ++ ; init(); while(m--) { int u,v; scanf("%d%d",&u,&v); addedge(u,v); addedge(v,u); } for(int i=1;i<=n;i++) if(!vis[i]) tarjan(i); scanf("%d" ,&q); printf("Case %d:\n", cas); while(q--) { int u,v; scanf("%d%d" ,&u,&v); lca(u,v); printf("%d\n",ans); } printf("\n"); } return 0;}
间遇到桥就把桥的标记删除,画一下图就清楚了
0 0
- poj3694 连通图+LCA
- LCA+桥poj3694
- poj3694 Network 无向图tarjan求桥+LCA
- 2017暑假集训 div1 连通图(1) POJ3694 &&POJ3177
- POJ3694 Network 割边+LCA
- poj3694(割边,LCA)
- POJ3694 Network 割边 LCA
- poj3694 Network 【图论-Tarjan-Lca】
- POJ3694-Network(Tarjan缩点+LCA)
- hdu2460&&poj3694 缩点+lca变形
- poj3694--Network(双连通缩点+lca)
- Network-POJ3694并查集+LCA
- POJ3694 Network(边双连通+LCA)
- hdu2460 poj3694 求桥 + 求lca
- poj3694 LCA+并查集+tarjan求割边
- Network-POJ3694并查集+LCA
- poj3694
- poj3694
- UI-滚动视图(滚动视图)
- Yoshua Bengio等大神传授:26条深度学习经验
- Android4.1添加新的按键(2)
- LoadRunner性能图表分析
- mantis 实验报告
- poj3694 连通图+LCA
- 一道2015年百度笔试编程题-四则运算计算器
- 容易被忽视的Linux磁盘配额设置
- PLSQL Developer 运行SQL脚本时插入数据库中数据乱码问题
- JAVA如何把一个float四舍五入到小数点后2位,4位,或者其它指定位数.
- 【笔试】45、统计文件中单词的个数
- 关于activity之间通过bundle传值
- 编写程序输出100以内的素数
- 北大某客座教授推荐 改变一个人价值观的书