分享web开发知识

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

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

【POJ3417】Network

发布时间:2023-09-22 06:26责任编辑:白小东关键词:暂无标签

关于lca和树上差分的题目。

根据题目描述,主要边是一棵树,附加边会和主要边构成一个环,如果我们第一步切断了一条主要边,我们下一步就必须切断一条附加边才能符合题意。

所以,我们可以认为一条附加边(x,y)把树上x,y之间的路径覆盖了一遍,我们需要统计每条主要边被覆盖多少次即可。具体地,如果第一步我们切断被覆盖0次的边(这条边上没有附加边,切断一次就已经不连通了),那么我们第二次可以切断m条附加边的任意一条。如果我们切断覆盖一次的边,那么我们第二次的方法唯一确定。如果我们第一步切断被覆盖2次或以上的边,那么我们无论如何也无法切断整个图。这样我们就得到了答案。

我们使用树上差分来解决。对于每一条附加边(x,y),我们将x,y的权值分别加1,将lca(x,y)的权值-2,之后我们遍历一遍这棵树,设tot[x]表示以x为根的子树的权值之和,那么f[x]就是x与他的父亲的路径被覆盖的次数。

 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 typedef long long ll; 7 inline int read() { 8 ????int ret=0; 9 ????int op=1;10 ????char c=getchar();11 ????while(c<‘0‘||c>‘9‘) {if(c==‘-‘) op=-1; c=getchar();}12 ????while(c<=‘9‘&&c>=‘0‘) ret=ret*10+c-‘0‘,c=getchar();13 ????return ret*op;14 }15 struct node {16 ????int next,to;17 }a[100010<<1];18 int num,head[100010<<1];19 int n,m,tot[100010],fa[100010][25],d[100010];20 inline void add(int from,int to) {21 ????a[++num].next=head[from];22 ????a[num].to=to;23 ????head[from]=num;24 }25 void dfs(int u,int f) {26 ????d[u]=d[f]+1;27 ????fa[u][0]=f;28 ????for(int i=0;i<20;i++)29 ????????fa[u][i+1]=fa[fa[u][i]][i];30 ????for(int i=head[u];i;i=a[i].next) {31 ????????int v=a[i].to;32 ????????if(v==f) continue ;33 ????????dfs(v,u);34 ????}35 }36 int lca(int x,int y) {37 ????if(d[x]<d[y]) swap(x,y);38 ????for(int i=20;i>=0;i--) {39 ????????if(d[fa[x][i]]>=d[y]) x=fa[x][i];40 ????????if(x==y) return x;41 ????}42 ????for(int i=20;i>=0;i--) {43 ????????if(fa[x][i]!=fa[y][i]) {44 ????????????x=fa[x][i];45 ????????????y=fa[y][i];46 ????????}47 ????}48 ????return fa[x][0];49 }50 int calc(int u,int f) {51 ????for(int i=head[u];i;i=a[i].next) {52 ????????int v=a[i].to;53 ????????if(v==f) continue ;54 ????????tot[u]+=calc(v,u);55 ????}56 ????return tot[u];57 }58 int main() {59 ????n=read(); m=read();60 ????for(int i=1;i<n;i++) {61 ????????int x=read(),y=read();62 ????????add(x,y);63 ????????add(y,x);64 ????}65 ????dfs(1,0);66 ????for(int i=1;i<=m;i++) {67 ????????int x=read(),y=read();68 ????????tot[x]++;69 ????????tot[y]++;70 ????????tot[lca(x,y)]-=2;71 ????}72 ????calc(1,0);73 ????int ans=0;74 ????for(int i=1;i<=n;i++) {75 ????????if(tot[i]==0&&i!=1) ans+=m;76 ????????if(tot[i]==1) ans++;77 ????}78 ????printf("%d\n",ans);79 ????return 0;80 }
AC Code

【POJ3417】Network

原文地址:https://www.cnblogs.com/shl-blog/p/10800522.html

知识推荐

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