HDU 5452-C - Minimum Cut 树链剖分
来源:互联网 发布:中级经济师题库软件 编辑:程序博客网 时间:2024/06/06 07:03
题意:
给出一个图G,给出里面的一颗生成树T,
找出一个割集,只包含T中的一条边,
让你输出边数最小的割集,的边数.
首先我们剖分一下生成树T。
接下来处理G中的其他边,对于这条边X,必然能在T上形成一个环,那么我们给这个环上(其实对于T是一条链)的所有点+1,
代表,如果以这些边的某一条作为我们选中的割集中的边的话,它将必须再删掉这个边X.
最后统计一下T中每条边,如果选择它作为割集的话,这个割集的大小应该是 val+1(本身)
#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>#include <vector>#include <queue>#include <set>#include <map>#include <string>#include <math.h>#include <stdlib.h>#include <time.h>using namespace std;typedef long long ll; const int MAXN = 201324+50;int n,m;struct Edge{ int to,next;} edge[MAXN*2];int head[MAXN],tot;int top[MAXN];//top[v]表示v所在的重链的顶端节点int fa[MAXN]; //父亲节点int deep[MAXN];//深度int num[MAXN];//num[v]表示以v为根的子树的节点数int p[MAXN];//p[v]表示v与其父亲节点的连边在线段树中的位置int fp[MAXN];//和p数组相反int son[MAXN];//重儿子int pos;int out[MAXN];//dfs序void init(){ tot = 0; memset(head,-1,sizeof(head)); pos = 0; memset(son,-1,sizeof(son));}void addedge(int u,int v){ edge[tot].to = v; edge[tot].next = head[u]; head[u] = tot++;}void dfs1(int u,int pre,int d) //第一遍dfs求出fa,deep,num,son{ deep[u] = d; fa[u] = pre; num[u] = 1; for(int i = head[u]; i != -1; i = edge[i].next) { int v = edge[i].to; if(v != pre) { dfs1(v,u,d+1); num[u] += num[v]; if(son[u] == -1 || num[v] > num[son[u]]) son[u] = v; } }}void getpos(int u,int sp) //第二遍dfs求出top和p{ top[u] = sp; p[u] = ++pos; fp[p[u]] = u; if(son[u]!=-1) getpos(son[u],sp); for(int i = head[u] ; i != -1; i = edge[i].next) { int v = edge[i].to; if(v != son[u] && v != fa[u]) getpos(v,v); } out[u]=pos;}struct TREE{ int tree[21234] ; void init() { memset(tree,0,sizeof tree); } int lowbit(int x) { return x&-x; } void add(int x,int value) { for (int i=x; i<=n; i=i+lowbit(i)) { tree[i]+=value; } } int get(int x) { int sum=0; for (int i=x; i; i-=lowbit(i)) { sum+=tree[i]; } return sum; } void update_edge(int u,int v)//查询u->v链的sum { int f1=top[u],f2=top[v]; ll tmp=0; while(f1!=f2) { if (deep[f1]<deep[f2]) { swap(f1,f2); swap(u,v); } // tmp+=(tmp,update(1,1,pos,p[f1],p[u])); add(p[f1],1); add(p[u]+1,-1); u=fa[f1],f1=top[u]; } if (deep[u]>deep[v] ) swap(u,v); // update(1,1,pos,p[son[u]],p[v])); //若val(u)是u到fu的边权,则用son[u] add(p[son[u]],1); add(p[v]+1,-1); }};TREE tp; int main(){int cnt=1;//freopen("in.txt","r",stdin); int t; cin>>t; while(t--) { init(); tp.init(); scanf("%d%d",&n,&m); int u,v; for (int i=1; i<n; i++) { scanf("%d%d",&u,&v); addedge(u,v); addedge(v,u); } dfs1(1,0,0); getpos(1,1); //tp.build(1,pos,1); int ans=m; for (int i=1; i<=m-n+1; i++) { scanf("%d%d",&u,&v); tp.update_edge(u,v); } for (int i=2; i<=n; i++) ans=min(ans,tp.get(i)+1); // for (int i=1;i<=n;i++) // printf("%d : %d\n",fp[i],tp.get(i)); printf("Case #%d: %d\n",cnt++,ans); } return 0;}
0 0
- HDU 5452-C - Minimum Cut 树链剖分
- hdu 5452 Minimum Cut(树链剖分)
- HDU 5452 Minimum Cut
- hdu 5452 Minimum Cut
- hdu 5452 Minimum Cut
- HDU 5452 Minimum Cut 树链剖分 + LCA
- 【LCA】HDU 5452Minimum Cut
- hdu 5452 Minimum Cut (LCA)
- hdu 5452 Minimum Cut(树链剖分+差分前缀和)
- [HDU 5452] Minimum Cut (树链剖分+树状数组)
- HDU 5631Minimum Cut-Cut
- HDU 5452 Minimum Cut(LCA+DFS)
- Minimum Cut (hdu 5452 离线LCA)
- HDU 5452 Minimum Cut(贪心)
- hdu 5432 Minimum Cut 树链剖分nlogn
- Smallest Minimum Cut HDU
- HDU 5452 Minimum Cut (2015年沈阳赛区网络赛C题)
- hdu 6124 Smallest Minimum Cut
- 51Nod-1412-AVL树的种类
- Bad Cowtractors(最大生成树与判定)
- 78. Subsets &90. Subsets II
- CSS文本样式
- Out of Hay(最小生成树的最大权)
- HDU 5452-C - Minimum Cut 树链剖分
- Agri-Net(最小生成树)
- 大二入学感慨
- JAVA基础--LinkedHashSet 和 LinkedHashMap
- Wormholes(负圈)
- Java深入 - Java内存区域详解
- 操作系统概述
- Gym 100851AAdjustment Office 解题报告
- Six Degrees of Cowvin Bacon(最短路)