题目链接:点击查看

题目大意:(摘自大蓝书)Dark是人类内心的黑暗的产物,古今中外的勇者们都试图打倒它。经过研究,你发现Dark呈现无向图的结构,图中有N个节点和两类边,一类边被称为主要边,而另一类被称为附加边。Dark有N-1条主要边,并且Dark的任意两个节点之间都存在一条只由主要边构成的路径。另外,Dark还有M条附加边。

你的任务是把Dark斩为不连通的两部分。一开始Dark的附加边都处于无敌状态,你只能选择一条主要边切断。一旦你切断了一条主要边,Dark就会进入防御模式,主要边会变为无敌的状态,而附加边可以被切断。但是你的能力只能再切断Dark的一条附加边。现在你想要知道,一共有多少种方案可以击败Dark。注意,就算你第一步切断主要边之后就已经把Dark斩为两截,你也需要切断一条附加边才算击败了Dark。

N<=1e5,M<=1e5,数据保证答案不超过2^31-1

题目分析:本来是想学网络流的,顺手翻到了这个题,感觉和前两天做过的那道题很像,就拿来做了做,发现真的是大同小异的一个题目,之前那个树上差分的题目求的是最小去掉几条边才能让整棵树分成两个部分,这个题目只让去掉两条边,一条树上的边,一条树外的边,问有多少种方案能将整棵树分为两半,因为题目也提示了,第一步切断树内的边后也是还需要再切断一条树外的边才算击败,那么我们可以分类讨论一下,假设现在我们已经求出所有附加边对主要边的贡献为sum[i]了:

  1. 若sum[i]==0,说明切断当前边i,即可让整棵树分为两部分,那么我们只需要再随意切断一条边就可以击败Dark,所以总贡献为m
  2. 若sum[i]==1,说明切断当前边i后,还需要切断给sum[i]提供贡献的那条附加边,所以情况是唯一的,此时贡献为1
  3. 若sum[i]>=2,说明切断当前边i后,只切断一条附加边是无法满足条件的,所以此时的贡献为0

按照上面的情况,分类讨论加权答案即可

上代码之前不得不吐槽两句,我是真的佛了,poj的评测机到底什么时候才能支持C++11?对于我这个懒癌患者极度不友好,先不说stl里的无序map和双端队列用不了,连auto也用不了,我干脆用vc++6.0编代码陪你一起回到上个世纪好不好

限制那么多也就算了,题意不明,你不说明白,鬼知道你默认的是多组输入?

这个题我是十一点半写完的,交上去第一发编译错误,第二发编译错误,第三发超时,我就想应该是邻接表太慢了,换了一发链式前向星,然后,poj就崩了。。崩了半小时交上去WA了,把代码拿下来换上了多组输入,然后poj又崩了,半个小时之后终于好了,终于A了,我真的佛了

最后,辣鸡poj

代码:

#include<iostream>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<climits>
#include<cmath>
#include<cctype>
#include<stack>
#include<queue>
#include<list>
#include<vector>
#include<set>
#include<map>
#include<sstream>
using namespace std;typedef long long LL;const int inf=0x3f3f3f3f;const int N=1e5+100;int n,m,limit;struct Edge
{int to,next;
}edge[N<<1];int head[N],cnt;//链式前向星用int val[N];//树上差分用int deep[N],dp[N][20];//树上倍增用void addedge(int u,int v)
{edge[cnt].to=v;edge[cnt].next=head[u];head[u]=cnt++;edge[cnt].to=u;edge[cnt].next=head[v];head[v]=cnt++;
}void dfs1(int u,int f,int dep)//树上倍增
{deep[u]=dep;dp[u][0]=f;for(int i=1;i<=limit;i++)dp[u][i]=dp[dp[u][i-1]][i-1];for(int i=head[u];i!=-1;i=edge[i].next){int v=edge[i].to;if(v==f)continue;dfs1(v,u,dep+1);}
}int LCA(int a,int b)
{if(deep[a]<deep[b])swap(a,b);for(int i=limit;i>=0;i--)if(deep[a]-deep[b]>=(1<<i))a=dp[a][i];if(a==b)return a;for(int i=limit;i>=0;i--)if(dp[a][i]!=dp[b][i]){a=dp[a][i];b=dp[b][i];}return dp[a][0];
}int sum[N];//树上前缀和void dfs2(int u,int f)//树上前缀和
{sum[u]=val[u];for(int i=head[u];i!=-1;i=edge[i].next){int v=edge[i].to;if(v==f)continue;dfs2(v,u);sum[u]+=sum[v];}
}void init()
{memset(head,-1,sizeof(head));memset(val,0,sizeof(val));limit=log2(n)+1;
}int main()
{
//  freopen("input.txt","r",stdin);
//  ios::sync_with_stdio(false);while(scanf("%d%d",&n,&m)!=EOF){init();for(int i=1;i<n;i++){int u,v;scanf("%d%d",&u,&v);addedge(u,v);}dfs1(1,0,0);for(int i=1;i<=m;i++){int u,v;scanf("%d%d",&u,&v);val[u]++;val[v]++;val[LCA(u,v)]-=2;}dfs2(1,0);int ans=0;for(int i=2;i<=n;i++){if(sum[i]==0)ans+=m;else if(sum[i]==1)ans++;}printf("%d\n",ans);}return 0;
}

POJ - 3417 Network(树上差分)相关推荐

  1. POJ 3417 Network

    本文转载:http://www.cnblogs.com/YoungNeal/p/8530398.html 题目大意: 给定一棵树,有 n-1 条树边,m 条非树边,有两次割边的机会,第一次只能割树边, ...

  2. POJ - 3417 Network LCA+树上差分

    思路:首先来说,给一个树加一条边肯定要构成一个环,我们假设加了该边后产生的环上的每一条边都累计加一. 假设这条边是a到b,那么其实就是原树a->lca(a,b)到b->lca(a,b)上的 ...

  3. [Codeforces 555E]Case of Computer Network(Tarjan求边-双连通分量+树上差分)

    [Codeforces 555E]Case of Computer Network(Tarjan求边-双连通分量+树上差分) 题面 给出一个无向图,以及q条有向路径.问是否存在一种给边定向的方案,使得 ...

  4. 【割边缩点】解题报告:POJ - 3694 - Network(Tarjan割边缩点 + LCA + 并查集优化)

    POJ - 3694 - Network 给定一张N个点M条边的无向连通图,然后执行Q次操作,每次向图中添加一条边,并且询问当前无向图中"桥"的数量.N≤105,M≤2∗105,Q ...

  5. 解题报告:AcWing 352. 闇の連鎖(树上差分、方案统计)

    https://www.acwing.com/problem/content/354/ 在没有附加边的情况下,我们发现这是一颗树,那么再添加条附加边(x,y)后,会造成(x,y)之间产生一个环 如果我 ...

  6. 模板 - LCA最近公共祖先(倍增法、Tarjan、树上差分、LCA优化的次小生成树)

    整理的算法模板合集: ACM模板 注意x和y的LCA可以是x或者y本身 一.LCA的在线倍增算法 /*给定一棵包含 n个节点的有根无向树,有 m个询问,每个询问 给出了一对节点的编号 x和 y,询问 ...

  7. [NOIP 2015]运输计划-[树上差分+二分答案]-解题报告

    [NOIP 2015]运输计划 题面: A[NOIP2015 Day2]运输计划 时间限制 : 20000 MS 空间限制 : 262144 KB 问题描述 公元 2044 年,人类进入了宇宙纪元. ...

  8. 洛谷P2680 运输计划(倍增LCA + 树上差分 + 二分答案)

    [题目链接] [思路]: 根据题意可以明显看出,当所有任务都完成时的时间是最终的结果,也就是说本题要求,求出最小的最大值. 那这样的话就暗示了将答案二分,进行check. [check方法]: 如果说 ...

  9. 差分数组 and 树上差分

    差分数组 定义 百度百科中的差分定义 //其实这完全和要讲的没关系 qwq 进去看了之后是不是觉得看不懂? 那我简单概括一下qwq 差分数组de定义:记录当前位置的数与上一位置的数的差值. 栗子 容易 ...

最新文章

  1. 【Scratch】青少年蓝桥杯_每日一题_7.01_正五边形组成的美丽春花
  2. svm分类器训练详细步骤_「五分钟机器学习」向量支持机SVM——学霸中的战斗机...
  3. Linux 下用C语言连接 sqlite
  4. NutzWk企业级开源开发框架 v5.2.6
  5. 均值(Mean)和均值标准误差(S.E. Mean)
  6. ##R语言生信作图之UpsetR做交集图
  7. 64位电脑c语言程序下载,vc2010 x64位
  8. java音乐登陆界面_onlinemusic java在线音乐平台,实现了基本的注册登录功能,有界面,对 的初学者有帮助 Jsp/Servlet 238万源代码下载- www.pudn.com...
  9. 关于 librecad 的中文支持
  10. HTML5前端开发之基础篇
  11. 揭开TCP传输性能优化的秘密
  12. 医学计算机论文,医学图像数据库-外文翻译(计算机论文,医学论文适合)
  13. 怎样申请MAC地址?
  14. Feed Ratios
  15. 如何在各种非三星电脑上安装Samsung Notes三星笔记
  16. 深信服AD应用交付介绍
  17. 零基础 学 零知识证明
  18. [讲座论坛] 应对气候变化的中国视角
  19. 网络信息安全之基于时间的安全模型(PDR和PPDR模型)
  20. 虚假新闻检测论文阅读(七):A temporal ensembling based semi-supervised ConvNet for the detection of fake news

热门文章

  1. 集中式整合之加入springsecurity
  2. java遍历目录下的包括子目录下的所有文件
  3. 获取指定包名下的所有类
  4. 本地消息表实现机制讲解
  5. docker启动失败,报docker dead but pid file exists,处理方式
  6. 文件上传案例的服务器端
  7. 数据库-数据库的介绍
  8. 开始使用Spring Cloud实战微服务
  9. activemq安全机制
  10. java 调用 dll 乱码_java调用c++ dll出现中文乱码