HDU 5452——Minimum Cut——————【树链剖分+差分前缀和】ACdream 1429——Diversion——————【树链剖分】
Minimum Cut
Time Limit: 3000/2000 MS (Java/Others) Memory Limit: 65535/102400 K (Java/Others)
Total Submission(s): 895 Accepted Submission(s): 387
We say that a cut in G respects T if it cuts just one edges of T.
Since love needs good faith and hypocrisy return for only grief, you should find the minimum cut of graph G respecting the given spanning tree T.
The first line of the input is a single integer t (1≤t≤5) which is the number of test cases.
Then t test cases follow.
Each test case contains several lines.
The first line contains two integers n (2≤n≤20000) and m (n−1≤m≤200000).
The following n−1 lines describe the spanning tree T and each of them contains two integers u and v corresponding to an edge.
Next m−n+1 lines describe the undirected graph G and each of them contains two integers u and v corresponding to an edge which is not in the spanning tree T.
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5;
struct Edge{
int v,w,next;
}edges[maxn*5];
int head[maxn];
int fa[maxn],dep[maxn],siz[maxn],son[maxn];
int top[maxn],w[maxn];
int c[maxn];
int tot,totw;
const int INF=0x3f3f3f3f;
void init(){
tot=0;
memset(head,-1,sizeof(head));
memset(son,-1,sizeof(son));
}
void addedge(int _u,int _v){
edges[tot].v=_v;
edges[tot].next=head[_u];
head[_u]=tot++;
edges[tot].v=_u;
edges[tot].next=head[_v];
head[_v]=tot++;
}
void dfs1(int u,int _fa,int _dep ){ //得到dep数组、fa数组、siz数组、son数组
dep[u] = _dep;
fa[u] = _fa;
siz[u] = 1;
for(int i=head[u]; i!=-1; i=edges[i].next){
Edge &e = edges[i];
if(e.v != _fa){
dfs1(e.v,u, _dep+1);
siz[u]+=siz[ e.v ];
if(son[u]==-1 || siz[son[u]] <siz[e.v]){
son[u] = e.v;
}
}
}
}
void dfs2(int u,int _top){ //得到top数组、w数组
top[u]=_top;
w[u]=totw++;
if(son[u]!=-1){
dfs2(son[u],_top);
for(int i=head[u]; i != -1; i = edges[i].next){
Edge &e = edges[i];
if(e.v != fa[u]&&e.v!=son[u]){
dfs2(e.v,e.v);
}
}
}
}
void update(int u,int v,int val){ //修改u---v路径上的权值
int f1=top[u],f2=top[v]; //找到u,v所在重链的链头
while(f1!=f2){ //处理不在同一条重链上的情况
if(dep[f1]<dep[f2]){
swap(f1,f2);
swap(u,v);
}
c[w[f1]] +=val; //这里用的是差分前缀和的方法实现
c[w[u]+1]-=val;
u=fa[f1];
f1=top[u];
}
if(dep[u]>dep[v]){ //让u处于靠近根的位置
swap(u,v);
}
c[w[son[u]]]+=val; //处理在同一条重链上的情况
c[w[v]+1]-=val;
}
int main(){
int t,n,m,cnt=0;
scanf("%d",&t);
while(t--){
init();
scanf("%d%d",&n,&m);
int a,b;
for(int i=1;i<=n-1;i++){
scanf("%d%d",&a,&b);
addedge(a,b);
}
dfs1(1,-1,1);
totw=1;
dfs2(1,1);
memset(c,0,sizeof(c));
for(int i=1;i<=m-n+1;i++){
scanf("%d%d",&a,&b);
update(a,b,1);
}
for(int i=1;i<=n;i++){
c[i]+=c[i-1];
}
int ans=INF;
for(int i=1;i<=n;i++){
if(c[i]!=0&&c[i]){
ans=min(ans,c[i]);
}
}
printf("Case #%d: %d\n",++cnt,ans+1);
}
return 0;
}
Diversion
Problem Description
Let us denote the number of stone roads needed to get from city u to city v as s(u, v). The roads were created long ago and follow the strange rule: if two cities u and v are connected by a road (no matter,stone or country), then either s(1, u) + s(u, v) = s(1, v ) or s(1, v ) + s(v, u) = s(1, u).
The king of Edgeland is planning to attack Farland. He is planning to start his operation by destroying some roads. Calculations show that the resources he has are enough to destroy one stone road and one country road. The king would like to destroy such roads that after it there were at least two cities in Farland not connected by roads any more.
Now he asks his minister of defense to count the number of ways he can organize the diversion. But the minister can only attack or defend, he cannot count. Help him!
Input
Output
Output one integer number — the number of ways to organize the diversion.
Sample Input
6 7
1 2 1
2 3 1
1 4 0
3 4 1
4 5 1
3 6 0
5 6 1
Sample Output
4 解释:这个题目跟上面那个基本一样,只是最后让求的结果略有不同。这个题目问只同时删掉树上一条边,和新加的边能让图不连通的方式有多少种。那么只需要统计最后边权为1的边有多少条即可。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5;
struct Edge{
int v,w,next;
}edges[maxn*5];
struct Country{
int x,y;
}countrys[maxn];
int head[maxn];
int fa[maxn],dep[maxn],siz[maxn],son[maxn];
int top[maxn],w[maxn];
int c[maxn];
int tot,totw;
const int INF=0x3f3f3f3f;
void init(){
tot=0;
memset(head,-1,sizeof(head));
memset(son,-1,sizeof(son));
}
void addedge(int _u,int _v){
edges[tot].v=_v;
edges[tot].next=head[_u];
head[_u]=tot++;
edges[tot].v=_u;
edges[tot].next=head[_v];
head[_v]=tot++;
}
void dfs1(int u,int _fa,int _dep ){ //得到dep数组、fa数组、siz数组、son数组
dep[u] = _dep;
fa[u] = _fa;
siz[u] = 1;
for(int i=head[u]; i!=-1; i=edges[i].next){
Edge &e = edges[i];
if(e.v != _fa){
dfs1(e.v,u, _dep+1);
siz[u]+=siz[ e.v ];
if(son[u]==-1 || siz[son[u]] <siz[e.v]){ //得到u的重儿子
son[u] = e.v;
}
}
}
}
//top[i]表示i节点所在重链的链头节点、w[i]表示i节点的父边在线段中的位置
void dfs2(int u,int _top){ //得到top数组、w数组
top[u]=_top;
w[u]=totw++;
if(son[u]!=-1){
dfs2(son[u],_top);
for(int i=head[u]; i != -1; i = edges[i].next){
Edge &e = edges[i];
if(e.v != fa[u]&&e.v!=son[u]){
dfs2(e.v,e.v);
}
}
}
}
void update(int u,int v,int val){ //修改u---v路径上的权值
int f1=top[u],f2=top[v]; //找到u,v所在重链的链头
while(f1!=f2){ //处理不在同一条重链上的情况
if(dep[f1]<dep[f2]){
swap(f1,f2);
swap(u,v);
}
c[w[f1]] +=val; //这里用的是差分前缀和的方法实现
c[w[u]+1]-=val;
u=fa[f1];
f1=top[u];
}
if(dep[u]>dep[v]){ //让u处于靠近根的位置
swap(u,v);
}
c[w[son[u]]]+=val; //处理在同一条重链上的情况
c[w[v]+1]-=val;
}
int main(){
int n,m,cnt=0,mm;
while( scanf("%d%d",&n,&m)!=EOF){
mm=0;
init();
int a,b,cc;
for(int i=1;i<=m;i++){
scanf("%d%d%d",&a,&b,&cc);
if(cc==1)
addedge(a,b);
else countrys[++mm].x=a,countrys[mm].y=b;
}
dfs1(1,-1,1);
totw=1;
dfs2(1,1);
memset(c,0,sizeof(c));
for(int i=1;i<=mm;i++){
a=countrys[i].x;
b=countrys[i].y;
update(a,b,1);
}
for(int i=1;i<=n;i++){
c[i]+=c[i-1];
}
int ans=0;
for(int i=2;i<=n;i++){
if(c[i]==1){
ans++;
}
}
printf("%d\n",ans);
}
return 0;
}
HDU 5452——Minimum Cut——————【树链剖分+差分前缀和】ACdream 1429——Diversion——————【树链剖分】的更多相关文章
- Hdu 5452 Minimum Cut (2015 ACM/ICPC Asia Regional Shenyang Online) dfs + LCA
题目链接: Hdu 5452 Minimum Cut 题目描述: 有一棵生成树,有n个点,给出m-n+1条边,截断一条生成树上的边后,再截断至少多少条边才能使图不连通, 问截断总边数? 解题思路: 因 ...
- hdu 5452 Minimum Cut 树形dp
Minimum Cut Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=54 ...
- HDU 5452 Minimum Cut(LCA)
http://acm.hdu.edu.cn/showproblem.php?pid=5452 题意: 有一个连通的图G,先给出图中的一棵生成树,然后接着给出图中剩余的边,现在要删除最少的边使得G不连通 ...
- HDU 5452 Minimum Cut
链接:http://acm.hdu.edu.cn/showproblem.php?pid=5452题目大意: 给你一个图G,图中包含一颗生成树.要求只能删除生成树内的一条边,使得图不联通.问最小的删除 ...
- HDU 5452 Minimum Cut (Spaning Tree)
生成树的上的一个非根结点对应一条生成树上的边,然后这个结点的子树上连出去的边就对应去掉这条边的割, 然后就可以对树外的边求LCA,在LCA上标记,利用这个信息可以算出有多少条边在子树上,以及有多少条边 ...
- 洛谷 P3258 [JLOI2014]松鼠的新家 树链剖分+差分前缀和优化
目录 题面 题目链接 题目描述 输入输出格式 输入格式 输出格式 输入输出样例 输入样例: 输出样例: 说明 说明 思路 AC代码 优化 优化后AC代码 总结 题面 题目链接 P3258 [JLOI2 ...
- hdu 1394 Minimum Inversion Number(这道题改日我要用线段树再做一次哟~)
Problem Description The inversion number of a given number sequence a1, a2, ..., an is the number of ...
- ACdream 1424 Diversion( 树链剖分 )
Diversion Time Limit: 2000/1000MS (Java/Others) Memory Limit: 128000/64000KB (Java/Others) Submit St ...
- AcWing243一个简单的整数问题2(树状数组+差分+前缀和规律)
题目地址:https://www.acwing.com/problem/content/244/ 题目描述: 给定一个长度为N的数列A,以及M条指令,每条指令可能是以下两种之一: 1.“C l r d ...
随机推荐
- Mybatis下面的MapperScannerConfigurer 扫描器
Mybatis MapperScannerConfigurer 自动扫描 将Mapper接口生成代理注入到Spring Mybatis在与Spring集成的时候可以配置 Ma ...
- eclipse如何集成tomcat插件
刚在Eclipse官方网站下载的Eclipse,需要自己手动安装tomcat插件才能配置tomcat服务器.网上好多安装方法,这里我就不厌其烦的再写一遍,边安装边截图讲解下安装方法. 首先你要去下载E ...
- Android中EditTex焦点设置和弹不弹出输入法的问题(转)
今天编程碰到了一个问题:有一款平板,打开一个有EditText的Activity会默认弹出输入法.为了解决这个问题就深入研究了下android中焦点Focus和弹出输入法的问题.在网上看了些例子都不够 ...
- Jmeter测试接口简单使用教程
1. 打开 解决 apache-jmeter-2.13 然后进解压后的然后点击bin 文件里面的jmeter.bat 打开jmeter 2. 添加测试组件 1:添 ...
- [cf839d]Winter is here容斥原理
题意:给定一个数列${a_i}$,若子序列长度为$k$,最大公约数为$gcd$,定义子序列的权值为$k*\gcd (\gcd > 1)$.求所有子序列的权值和. 答案对10^9+7取模. 解题 ...
- 解决PCL MLS : error LNK2019; error LNK2001 virtual MovingLeastSquares process performProcessing问题
PCL 基于多项式拟合的法线估计.点云平滑和数据重采样 在使用Window VS2010为开发平台,学习PCL点云库的时候,学到曲面重建(Surface).在测试下面的程序的时候,遇到了问题. #in ...
- hbase->Mapreduce->hbase
Hbase对Mapreduce API进行了扩展,方便Mapreduce任务读写HTable数据. package taglib.customer; import java.io.IOExceptio ...
- layui js中求某一天距今天有多少天
<script> lay('#version').html('-v'+ laydate.v); //执行一个laydate实例 laydate.render({ elem: '#test1 ...
- QueryString
- 如何使用visual studio 2017创建C语言项目
使用visual studio 2017创建一个C语言项目,步骤如下: (1)打开Visual Studio 2017环境后出现欢迎界面,如图1所示. 图1 Visual Studio 2017欢迎 ...