POJ 3694 Network 割边+LCA
来源:互联网 发布:中美俄三国关系知乎 编辑:程序博客网 时间:2024/04/23 16:41
这道题跟3177意思差不多,不过最后问的不一样,说是加入某条边后,问图内剩余的桥有多少。
这题的大概思路就是,先求割边并标记,然后缩点,形成一棵树,然后把这颗树上各个结点的父结点用dfs求出来,再然后就是LCA了,因为加入某条边后,树内会形成一个圈,这个圈上所有的边将不再是桥,可以发现跟LCA的关联。
求LCA用裸的方法就行,比较直观些,也好操作。
实际上,这道题也不一定要缩点,如果用缩点的思路来做的话,程序将十分麻烦。可以直接根据dfn值来进行LCA。因为,我们观察low[v] > dfn[u]这个条件,代表的意思就是v无法通过回边或者通过子女到达比u点更靠前的点,那么我们只需要标记v点即可表明割边。在进行LCA时,由于树的组成就是原图中的割边,所以在原图中,根据这个标记来判断是否将割边被转化为了普通边。
这道题邻接表的方法,我改用的数组模拟。这种方式还是有一定的好处的。
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <vector>#include <queue>#define MAXN 100005#define MAXM 555555#define INF 1000000000using namespace std;struct Edge{ int v, next;}edge[MAXM];int low[MAXN], dfn[MAXN], index, vis[MAXN], Dfn[MAXN];int e, n, m, head[MAXN];int cnt, bridge[MAXN], father[MAXN];void init(){ e = 0, index = 0, cnt = 0; memset(vis, 0, sizeof(vis)); memset(dfn, 0, sizeof(dfn)); memset(Dfn, 0, sizeof(Dfn)); memset(bridge, 0, sizeof(bridge)); memset(head, -1, sizeof(head)); for(int i = 1; i <= n; i++) father[i] = i;}void insert(int x, int y){ edge[e].v = y; edge[e].next = head[x]; head[x] = e++;}void tarjan(int u){ dfn[u] = low[u] = ++index; Dfn[u] = Dfn[father[u]] + 1; for(int i = head[u]; i != -1; i = edge[i].next) { int v = edge[i].v; if(!dfn[v]) { father[v] = u; tarjan(v); low[u] = min(low[u], low[v]); if(low[v] > dfn[u]) { cnt++; bridge[v] = 1; } } else if(v != father[u]) low[u] = min(low[u], dfn[v]); }}void LCA(int u, int v){ while(Dfn[u] > Dfn[v]) { if(bridge[u]) cnt--, bridge[u] = 0; u = father[u]; } while(Dfn[v] > Dfn[u]) { if(bridge[v]) cnt--, bridge[v] = 0; v = father[v]; } while(u != v) { if(bridge[u]) cnt--, bridge[u] = 0; if(bridge[v]) cnt--, bridge[v] = 0; u = father[u]; v = father[v]; }}void ask(){ int q, u, v; scanf("%d", &q); while(q--) { scanf("%d%d", &u, &v); LCA(u, v); printf("%d\n", cnt); } printf("\n");}int main(){ int cas = 0; while(scanf("%d%d", &n, &m) != EOF) { if(n == 0 && m == 0) break; printf("Case %d:\n", ++cas); init(); int x, y; while(m--) { scanf("%d%d", &x, &y); insert(x, y); insert(y, x); } tarjan(1); ask(); } return 0;}
- POJ 3694 Network(割边+LCA)
- POJ 3694 Network 割边+LCA
- POJ 3694 Network(割边+LCA)
- POJ 3694 Network 割边+LCA
- 【POJ 3694】 Network(割边<桥>+LCA)
- POJ3694 Network 割边+LCA
- POJ3694 Network 割边 LCA
- POJ 3694 Network 割边
- poj 3694 Network 边双连通+LCA
- poj 3694 Network (强联通分量缩点+割桥+lca查询)
- Tarjan+LCA POJ 3694 Network
- POJ 3694 Network (求割边 + LCA)
- POJ 3694 Network tarjan+LCA
- POJ 3694 Network(tarjan+lca)
- POJ 3694 双连通分量 割边 LCA
- poj 3694 Network(桥+边联通分量+LCA)
- poj 3694 Network 边双连通分量+LCA
- POJ 3694 Network (边双连通缩点、LCA)
- Linux信号处理机制
- Linux进程间通信之管道通信
- Linux驱动程序学习步骤经典收藏
- 简单配置Samba服务
- 嵌入式Linux操作系统学习规划
- POJ 3694 Network 割边+LCA
- LINUX CP命令详解
- 深入理解 Linux 内核
- agree to、discount、try out、obtain some patent、expand horizon、in the order
- 命名规范(Oracle数据库)
- IBM developerWorks 中国 Linux技术文档
- 我的2011 -- 折腾的一年
- 类似googleearth产品
- objective-c与java的几点不同 (转)