hdu 5452(树链刨分)
看到题目,想了挺长时间,发现不会,然后看着样子像是树上成段操作,所以查了下树链刨分,结果真的就是这个东西。。。
Minimum Cut
Time Limit: 3000/2000 MS (Java/Others) Memory Limit: 65535/102400 K (Java/Others)
Total Submission(s): 453 Accepted Submission(s): 180
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.
4 5
1 2
2 3
3 4
1 3
1 4
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <math.h>
using namespace std;
#define N 20020 int n,m;
struct node
{
int to,next;
}edge[2*N]; int pre[N],cnt;
int siz[N],son[N],top[N],dep[N],fa[N],w[N];
int index;
int cnt1[N]; void add_edge(int u,int v)
{
edge[cnt].to=v;
edge[cnt].next=pre[u];
pre[u]=cnt++;
} void dfs(int s,int deep,int father)
{
dep[s]=deep;
siz[s]=1;
fa[s]=father;
int mx=-1;
son[s]=0;
for(int p=pre[s];p!=-1;p=edge[p].next)
{
int v=edge[p].to;
if(v==father) continue;
dfs(v,deep+1,s);
if(siz[v]>mx)
{
mx=siz[v];
son[s]=v;
}
siz[s]+=siz[v];
}
} void dfs1(int s,int father)
{
if(son[s]!=0)
{
w[ son[s] ]=++index;
top[ son[s] ]=top[s];
dfs1(son[s],s);
}
for(int p=pre[s];p!=-1;p=edge[p].next)
{
int v=edge[p].to;
if(v==father||v==son[s]) continue;
w[v]=++index;
top[v]=v;
dfs1(v,s);
}
} int Scan() //输入外挂
{
int res=0,ch,flag=0;
if((ch=getchar())=='-')
flag=1;
else if(ch>='0'&&ch<='9')
res=ch-'0';
while((ch=getchar())>='0'&&ch<='9')
res=res*10+ch-'0';
return flag?-res:res;
} void Out(int a)//输出外挂
{
if(a>9)
Out(a/10);
putchar(a%10+'0');
} int in()
{
int flag = 1;
char ch;
int a = 0;
while((ch = getchar()) == ' ' || ch == '\n');
if(ch == '-') flag = -1;
else
a += ch - '0';
while((ch = getchar()) != ' ' && ch != '\n')
{
a *= 10;
a += ch - '0';
}
return flag * a;
} //你卡这个复杂度真的好吗,不过也怪自己学的少。 int main()
{
int T;
scanf("%d",&T);
int tt=1;
while(T--)
{
memset(pre,-1,sizeof(pre));
cnt=0;
scanf("%d%d",&n,&m);
for(int i=0;i<n-1;i++)
{
int x,y;
scanf("%d%d",&x,&y);
add_edge(x,y);
add_edge(y,x);
}
//然后就是进行树链刨分
dfs(1,1,1);
top[1]=1;
index=0;
w[1]=0;
dfs1(1,-1); memset(cnt1,0,sizeof(cnt1)); for(int i=n-1;i<m;i++)
{
int x,y;
scanf("%d%d",&x,&y); while(top[x]!=top[y])
{
if( top[x] > top[y] )
{
cnt1[w[top[x]] ]++;
cnt1[w[x]+1]--;
x = fa[ top[x] ];
}
else
{
cnt1[ w[ top[y] ] ]++;
cnt1[ w[y]+1 ]--;
y = fa[ top[y] ];
}
}
if(dep[x] < dep[y])
{
cnt1[ w[son[x] ] ]++;
cnt1[ w[y]+1 ]--;
}
else if(dep[x] >dep[y] )
{
cnt1[w[son[y]] ]++;
cnt1[w[x]+1 ]--;
} } int ans=10000000;
for(int i=1;i<=index;i++)
{
cnt1[i]+=cnt1[i-1];
ans=min(ans,cnt1[i]);
}
printf("Case #%d: ",tt++);
printf("%d\n",ans+1);
}
return 0;
}
hdu 5452(树链刨分)的更多相关文章
- HDU - 3966 树链刨分
题目传送门 操作就是询问某个点的值, 然后就是对一条路径上的值全部修改. 最基本的树刨题目了. 树刨的思想: 1. 对于每个点找到他的重儿子. void dfs1(int o, int u){ sz[ ...
- bzoj 5210(树链刨分下做个dp)
5210: 最大连通子块和 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 211 Solved: 65[Submit][Status][Discus ...
- xcoj 1103 插线板(树链刨分求最大子段和)
1103: 插线板 时间限制: 1 Sec 内存限制: 128 MB提交: 14 解决: 7 标签提交统计讨论版EditTestData 题目描述 从前有一堆古老的插线板,任意两个插线板之间只有一 ...
- 树链刨分(class版)
class版树链剖(刨)分 感谢沙华大佬的赞助 其实没什么太大变化,就是用了几次一顿乱指... CODE: #include<iostream> #include<cstdio> ...
- hdu 3804树链剖分+离线操作
/* 树链刨分+离线操作 题意:给你一棵树,和询问x,y 从节点x--节点1的小于等于y的最大值. 解:先建一个空树,将树的边权值从小到大排序,将询问y按从小到大排序 对于每次询问y将小于等于y的边权 ...
- HDU 3966 Aragorn's Story 树链拋分
一.写在前面 终于开始开坑link-cut-tree这个了,对于网上找到的大佬的前进路线,进行了一番研发,发现实际上可以实现对于树链拋分的制作.经历了若干长时间之后终于打了出来(为什么每次学什么东西都 ...
- hdu 5893 (树链剖分+合并)
List wants to travel Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/O ...
- hdu 5052 树链剖分
Yaoge’s maximum profit Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/ ...
- hdu 4897 树链剖分(重轻链)
Little Devil I Time Limit: 16000/8000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others ...
随机推荐
- vue - rimraf
rimraf 包的作用:以包的形式包装rm -rf命令,用来删除文件和文件夹的,不管文件夹是否为空,都可删除 const rimraf = require('rimraf'); rimraf('./t ...
- python 对比学习
python和java面向对象的不同 1.属性和方法 java中类的属性(static)除外,对象全部独立拥有: 而python中类的属性,其实例对象一个字段都没有.底层是这么搞的: 对象object ...
- cocos2d-x OpenGL ES 坐标系总结
很多教程都说cocos2d-x OpenGL ES世界坐标系原点在左下角,但至于为什么在左下角却从来没有人提过,这导致大部分人觉得这是OpenGL ES的规定,事实上这是错的.OpenGL ES的坐标 ...
- 取给定正整数的指定bit位開始的指定长度的数据
接口说明 原型: unsigned int GetBitsValue(unsigned int input, unsigned int startbit, unsigned int bitlen) 输 ...
- 基于windows api实现的共享锁/独占锁
众所周知,windows平台上实现线程同步.或者说资源的加锁与解锁的方法有内核事件.临界区.相互排斥量.信号量,甚至interlocked系列函数等多种手段. 可是在日常的编程中,我们使用这些手段对 ...
- PL/SQL 异常错误处理
异常错误处理 一个优秀的程序都应该可以正确处理各种出错情况,并尽可能从错误中恢复.ORACLE 提供异常情况(EXCEPTION)和异常处理(EXCEPTION HANDLER)来实现错误处理 ...
- The user specified as a definer ('root'@'%') does not exist
通常是因为root用户对全局host无訪问权限.因此仅仅要给root用户加入一个訪问权限就可以. 解决的方法: 登陆mysql .运行 mysql -u root -pPasswd mysql ...
- elasticsearch 使用快照方式迁移数据
注册快照仓库 ES是通过快照的方式来实现数据备份,并且是以增量的方式,所以一般第一次做的话会花费较长的时间.为了做快照,那么就需要注册一个快照仓库,告诉ES我们的快照应该如何保存以及将快照保存到哪里. ...
- Sklearn 中的 CrossValidation 交叉验证
1. 交叉验证概述 进行模型验证的一个重要目的是要选出一个最合适的模型,对于监督学习而言,我们希望模型对于未知数据的泛化能力强,所以就需要模型验证这一过程来体现不同的模型对于未知数据的表现效果. 最先 ...
- Centos 7 部署FTP服务简单版
第三方教程推荐与参考: http://blog.csdn.net/somehow1002/article/details/70232791 先安装成功了,有信心了.再进一步扩展配置. 1.安装vsft ...