分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 软件开发

poj 3417 Network(tarjan lca)

发布时间:2023-09-06 01:29责任编辑:赖小花关键词:暂无标签

poj 3417 Network(tarjan lca)

先给出一棵无根树,然后下面再给出m条边,把这m条边连上,然后每次你能毁掉两条边,规定一条是树边,一条是新边,问有多少种方案能使树断裂。

我们设添加了一条新边后,树形成了一个环,表示为x->y->lca(x,y),我们将其中的边都覆盖一次。添加了多条新边后,可知树上有些边是会被多次覆盖的,画图很容易发现,但一个树边被覆盖了2次或以上,它就是一条牢固的边,就是说毁掉它再毁掉任何一条新边都好,树都不会断裂。所以我们只要统计被覆盖过零次或一次的边即可。覆盖过零次的边,拆掉以后还能再拆任意一条新边,所以cnt+=m。覆盖过一次的边,拆掉后必须拆掉覆盖它的那个边,所以cnt++。剩下的就是求lca了。然而用nlogn的lca求法居然会超时。。所以只能用tarjan。

#include <cctype>#include <cstdio>using namespace std;const int maxn=1e5+5, maxm=1e5+5;struct Graph{ ???struct Edge{ ???????int to, next; Graph *bel; ???????inline int operator *(){ return to; } ???????Edge& operator ++(){ ???????????return *this=bel->edge[next]; } ???}; ???void addedge(int x, int y){ ???????Edge &e=edge[++cntedge]; ???????e.to=y; e.next=fir[x]; ???????e.bel=this; fir[x]=cntedge; ???} ???Edge& getlink(int x){ ???????return edge[fir[x]]; } ???Edge edge[maxm*2]; ???int cntedge, fir[maxn];}g, g2;inline int getint(){ ???char c; int re=0, flag=1; ???for (c=getchar(); !isdigit(c); c=getchar()) ???????if (c=='-') flag=-1; ???for (re=c-48; c=getchar(), isdigit(c); re=re*10+c-48); ???return re*flag;}int n, m, visit[maxn], fa[maxn], add[maxn];long long cnt;int find(int x){ ???return fa[x]==x?x:fa[x]=find(fa[x]);}void tarjan(int now, int par){ ???Graph::Edge e=g2.getlink(now); ???visit[now]=1; ???for (; *e; ++e) if (visit[*e]){ ???????add[find(*e)]-=2; ???????++add[now]; ++add[*e]; ???} ???e=g.getlink(now); ???//这个要写在后面!不然如果这个点的lca在它子树里,会算两遍 ???for (; *e; ++e){ ???????if (*e==par) continue; ???????tarjan(*e, now); ???????fa[*e]=now; ???}}int dfs(int now, int par){ //断开now上面的边 ???int v=add[now]; Graph::Edge e=g.getlink(now); ???for (; *e; ++e){ ???????if (*e==par) continue; ???????v+=dfs(*e, now); ???} ???if (now!=1){ ???????if (v==0) cnt+=m; ???????if (v==1) ++cnt; ???} ???return v;}int main(){ ???scanf("%d%d", &n, &m); int x, y; ???for (int i=1; i<=n; ++i) fa[i]=i; ???for (int i=1; i<n; ++i){ ???????x=getint(); y=getint(); ???????g.addedge(x, y); g.addedge(y, x); ???} ???for (int i=1; i<=m; ++i){ ???????x=getint(); y=getint(); ???????if (x==y){ continue; } ???????g2.addedge(x, y); ???????g2.addedge(y, x); ???} ???tarjan(1, 0); dfs(1, 0); ???printf("%lld\n", cnt); ???return 0;}

poj 3417 Network(tarjan lca)

原文地址:http://www.cnblogs.com/MyNameIsPc/p/8000120.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved