HDU
来源:互联网 发布:数控编程员岗位职责 编辑:程序博客网 时间:2024/05/25 01:34
传送门:HDU5452
题意:给出一个无向图G,求图G的最小边割集,并且使得割边中有且仅有一条属于图G的生成树T。
思路:考虑生成树中的每一条边i,将其去掉后生成树就被划分成两部分,则全图的割边就是那些跨越这两部分的边,将这些割边的数量记录为ans[i],但是求ans[]的过程显然不能暴力,考虑每条不在生成树中的边对答案的贡献,设其端点为u,v,则u -> v路径上所有边对应的ans[i]都应该++,但是这个过程也不能暴力,这时候就要用到imos和的思想了,详见:点击打开链接
也就是说我们只需要在ans[u]++, ans[v]++, ans[lca(u, v)] -= 2,然后最后再求一遍和就行了。
PS:我感觉这种做法是这个题的正解,看网上好多做法都是水过去的。
代码:
#include<bits/stdc++.h>using namespace std;#define MAXN 20050#define MAXM 200050#define inf 0x3f3f3f3ftypedef pair<int,int>P;int dep[MAXN], ans[MAXN];int f[20][MAXN], pre[MAXN];int cnt;struct node{ int v, next;node(int _v = 0, int _next = 0) : v(_v), next(_next) {}}mp[MAXM * 2];void init(){ cnt = 0; memset(pre, -1, sizeof(pre)); memset(ans, 0, sizeof(ans));}void add(int u, int v){mp[cnt] = node(v, pre[u]), pre[u] = cnt++;mp[cnt] = node(u, pre[v]), pre[v] = cnt++;}void dfs(int u, int fa){ dep[u] = dep[fa] + 1; for(int i = pre[u]; ~i; i = mp[i].next) { int v = mp[i].v; if(v == fa) continue; dfs(v, u); f[0][v] = u; }}int lca_init(int n){dep[1] = 1; dfs(1, 0); int k = 0,t = 1; while(t <= n)t <<= 1,k++; for(int i=0;i+1<k;i++) { for(int j=1;j<=n;j++) { f[i+1][j] = f[i][f[i][j]]; } } return k;}int lca(int u, int v, int MAX){ if(dep[u] < dep[v]) swap(u, v); int k = dep[u] - dep[v]; for(int i=0;i<MAX;i++) { if((k >> i) & 1) u = f[i][u]; } if(u == v)return u; for(int i=MAX-1;i>=0;i--) while(f[i][u] != f[i][v]) { u = f[i][u]; v = f[i][v]; } return f[0][u];}void get_ans(int u, int fa){ for(int i = pre[u]; ~i; i = mp[i].next) { int v = mp[i].v; if(v == fa) continue; get_ans(v, u); ans[u] += ans[v]; }}int main(){ int T, u, v, n, m, kase = 1; cin >> T; while(T--) { scanf("%d %d", &n, &m); init(); for(int i = 0; i < n - 1; i++) { scanf("%d %d", &u, &v); add(u, v);} int up = lca_init(n), fa; for(int i = n - 1; i < m; i++) { scanf("%d %d",&u, &v); fa = lca(u, v, up); ans[u]++, ans[v]++; ans[fa] -= 2; } get_ans(1, -1); printf("Case #%d: %d\n", kase++, *min_element(ans + 2, ans + n + 1) + 1); }}
阅读全文
0 0
- hdu
- hdu
- HDU
- hdu ()
- hdu
- hdu
- HDU
- HDU
- hdu
- hdu
- HDU
- Hdu
- hdu
- hdu-
- hdu
- hdu
- hdu
- HDU
- JAVAEE之web基础知识
- 494. Target Sum
- 非常详细的 Docker 学习笔记
- Spark transformation算子案例
- 透明Textbox的简单实现!
- HDU
- 【Ubuntu】我的Ubuntu 16.04 x64配置记录
- JAVAEE之Servlet入门
- HttpClient使用详解
- 《Python机器学习实战》第一章读书笔记:k-近邻算法
- on()的多事件绑定
- Android_小代码集合
- LeetCode 11. Container With Most Water解题报告
- GPT+UEFI双硬盘双系统安装