HDU 5452 Minimum Cut

Minimum Cut

Time Limit: 3000/2000 MS (Java/Others)    Memory Limit: 65535/102400 K (Java/Others)
Total Submission(s): 315    Accepted Submission(s): 120

Problem Description

Given a simple unweighted graph G (an undirected graph containing no loops nor multiple edges) with n nodes and m edges. Let T be a spanning tree of G.
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.

Input
The input contains several test cases.
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.

Output

For each test case, you should output the minimum cut of graph G respecting the given spanning tree T.

Sample Input

1

4 5

1 2

2 3

3 4

1 3

1 4

Sample Output

Case #1: 2

Source

2015 ACM/ICPC Asia Regional Shenyang Online

解题:先把树建好,添加非树边,会形成环,把环上的非树边都+1,最后树上的最小边+1就是答案

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int maxn = 20010;
 4 struct arc {
 5     int to,next;
 6     arc(int x = 0,int y = -1) {
 7         to = x;
 8         next = y;
 9     }
10 } e[500100];
11 int head[maxn],fa[maxn],top[maxn],de[maxn];
12 int siz[maxn],son[maxn],loc[maxn],c[maxn],tot,clk;
13 void add(int u,int v) {
14     e[tot] = arc(v,head[u]);
15     head[u] = tot++;
16 }
17 void FindHeavyEdge(int u,int father,int depth) {
18     fa[u] = father;
19     siz[u] = 1;
20     son[u] = -1;
21     de[u] = depth;
22     for(int i = head[u]; ~i; i = e[i].next) {
23         if(e[i].to == father) continue;
24         FindHeavyEdge(e[i].to,u,depth + 1);
25         siz[u] += siz[e[i].to];
26         if(son[u] == -1 || siz[e[i].to] > siz[son[u]])
27             son[u] = e[i].to;
28     }
29 }
30 void ConnectHeavyEdge(int u,int ancestor) {
31     top[u] = ancestor;
32     loc[u] = clk++;
33     if(son[u] != -1) ConnectHeavyEdge(son[u],ancestor);
34     for(int i = head[u]; ~i; i = e[i].next) {
35         if(e[i].to == fa[u] || son[u] == e[i].to) continue;
36         ConnectHeavyEdge(e[i].to,e[i].to);
37     }
38 }
39 void update(int u,int v) {
40     while(top[u] != top[v]) {
41         if(de[top[u]] < de[top[v]]) swap(u,v);
42         c[loc[top[u]]]++;
43         c[loc[u] + 1]--;
44         u = fa[top[u]];
45     }
46     if(u == v) return;
47     if(de[u] > de[v]) swap(u,v);
48     c[loc[son[u]]]++;
49     c[loc[v]+1]--;
50 }
51 int main() {
52     int kase,u,v,n,m,cs = 1;
53     scanf("%d",&kase);
54     while(kase--) {
55         memset(head,-1,sizeof head);
56         memset(c,0,sizeof c);
57         tot = clk = 0;
58         scanf("%d%d",&n,&m);
59         for(int i = 1; i < n; ++i) {
60             scanf("%d%d",&u,&v);
61             add(u,v);
62             add(v,u);
63         }
64         FindHeavyEdge(1,0,0);
65         ConnectHeavyEdge(1,1);
66         for(int i = 0; i <= m - n; ++i) {
67             scanf("%d%d",&u,&v);
68             update(u,v);
69         }
70         int ret = 0x3f3f3f3f;
71         for(int i = 1; i < clk; ++i) {
72             c[i] += c[i-1];
73             ret = min(ret,c[i]);
74         }
75         printf("Case #%d: %d\n",cs++,ret + 1);
76     }
77     return 0;
78 }

时间: 2024-09-13 01:17:52

HDU 5452 Minimum Cut的相关文章

Hdu 5452 Minimum Cut (2015 ACM/ICPC Asia Regional Shenyang Online) dfs + LCA

题目链接: Hdu 5452 Minimum Cut 题目描述: 有一棵生成树,有n个点,给出m-n+1条边,截断一条生成树上的边后,再截断至少多少条边才能使图不连通, 问截断总边数? 解题思路: 因为只能在生成树上截断一条边(u, v),所以只需要统计以v为根节点的子生成树里的节点与子生成树外的节点的边数就可以了.对于新加入的边(u', v')来说,只影响以LCA(u, v)为根节点的子树里面的节点.统计所有答案,扫一遍输出最小即可.(比赛的时候只统计叶子节点,给水过去了........233

hdu 5452 Minimum Cut 树形dp

Minimum Cut Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5452 Description Given a simple unweighted graph G (an undirected graph containing no loops nor multiple edges) with n nodes and m edges. Let T be a spa

HDU 5452——Minimum Cut——————【树链剖分+差分前缀和】

Minimum Cut Time Limit: 3000/2000 MS (Java/Others)    Memory Limit: 65535/102400 K (Java/Others)Total Submission(s): 895    Accepted Submission(s): 387 Problem Description Given a simple unweighted graph G (an undirected graph containing no loops nor

hdu 6214 Smallest Minimum Cut[最大流]

hdu 6214 Smallest Minimum Cut[最大流] 题意:求最小割中最少的边数. 题解:对边权乘个比边大点的数比如300,再加1 ,最后,最大流对300取余就是边数啦.. 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 #include<vector> 7 #in

hdu 1394 Minimum Inversion Number

题目链接:hdu 1394 Minimum Inversion Number 该题是求最小逆序对的扩展.可以使用树状数组来实现.对于$n$个数的序列$A$,其第$i$个数($i\in [0,n)$)的逆序数$r_i$可以表示为它的角标$i$减去在它之前且不大于它的数的个数.例如对序列A = {1,3,5,9,0,8,5,7,4,2}中的数,A[8] = 4.其逆序数$r_8 = 8 - 3 = 5$,第二个3表示三个在它前面且比它小的数:{1,3,0}.从而我们可以得到第$i$个数的逆序数公式:

hdu 1394 Minimum Inversion Number(线段树)

Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 10853    Accepted Submission(s): 6676 Problem Description The inversion number of a given number sequence a1, a2, ..., a

POJ2914 Minimum Cut 最小割集

题目大意是,给定N个顶点,M条边,两个顶点之间可能有多条边,求至少删除多少条边才能将该图分成两个子图. 最小割集,典型的算法Stoer-Wagner,就是那篇论文,这里也就不复制过来了,只是用Prim求最大生成树时,更新的"边"不是普通意义上的边,而是顶点到所有已划分集合中的所有点的边权值和,这里要特别注意~ 直接贴代码~ #include <stdio.h> #include <vector> #include <math.h> #include

Minimum Cut

Minimum Cut Time Limit: 3000/2000 MS (Java/Others)    Memory Limit: 65535/102400 K (Java/Others)Total Submission(s): 769    Accepted Submission(s): 340 Problem Description Given a simple unweighted graph G (an undirected graph containing no loops nor

HDU 1385 Minimum Transport Cost 最短路径题解

本题就是使用Floyd算法求所有路径的最短路径,并且需要保存路径,而且更进一步需要按照字典顺序输出结果. 还是有一定难度的. Floyd有一种很巧妙的记录数据的方法,大多都是使用这个方法记录数据的. 不过其实本题数据不是很大,一般太大的数据也无法使用Floyd,因为效率是O(N^3). 所以其实也可以使用一般的Floyd算法,然后增加个三维数组记录数据.下面就是这种做法,0ms过了. #include <stdio.h> #include <vector> using std::v