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 ...
随机推荐
- Asp.net 实现只能允许一个账号同时只能在一个地方登录
先上帮助类: /// <summary> /// 单点登录帮助类 /// </summary> public class SSOHelper { /// <summary ...
- 利用java mail发送邮件
import java.util.Date; import java.util.Properties; import javax.activation.DataHandler; import java ...
- Eclipse中插件的使用:maven /ant /tomcat
一:使用Eclipse构建Maven项目 http://blog.csdn.net/jackgaolei/article/details/11332249 二:Maven介绍,包括作用.核心概念.用法 ...
- mouseenter与mouseover的区别
mouseover 事件:只有在鼠标指针穿过被选元素时,才会触发. mouseover 事件:鼠标指针穿过任何子元素,都会触发. 请看例子的演示.
- mysql主从服务器复制原理
在实际企业应用环境当中,单台mysql数据库是不足以满足日后业务需求的.譬如服务器发生故障,没有备份服务器来提供服务的话,业务就得停止.介于这种情况,我们来学习一下mysql主从复制. 将Mysql的 ...
- [matlab]Monte Carlo模拟学习笔记
理论基础:大数定理,当频数足够多时,频率可以逼近概率,从而依靠概率与$\pi$的关系,求出$\pi$ 所以,rand在Monte Carlo中是必不可少的,必须保证测试数据的随机性. 用蒙特卡洛方法进 ...
- [Manacher+bit]Palindrome
https://nanti.jisuanke.com/t/15428 题目大意:离散表示的字符串,求其最长回文串长度. 解题关键:若只用Manacher算法,在统计sum时会超时,所以加一个树状数组来 ...
- IOS 完成来电归属地
首先是一个库:(有时间在上传) 然后设置一个工具类 .h @interface HMFoundLocation : NSObject AS_SINGLETON(HMFoundLocation) @pr ...
- 机器学习--K折交叉验证和非负矩阵分解
1.交叉验证 交叉验证(Cross validation),交叉验证用于防止模型过于复杂而引起的过拟合.有时亦称循环估计, 是一种统计学上将数据样本切割成较小子集的实用方法. 于是可以先在一个子集上做 ...
- 解决Navicat 无法连接mysql8.0
必须执行下面两个步骤,缺一不可. 一. mysql8.0加密方式与mysql5几加密方式不同,需要先更改加密方式. 更改加密方式 ALTERUSER 'root'@'localhost' ...