hdu5452 || 瀋陽網路賽1003題 最近公共祖先問題
http://acm.hdu.edu.cn/showproblem.php?pid=5452
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.
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.
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
/*
hdu5452 || 瀋陽網路賽1003題 最近公共祖先問題
題目大意:給定一個圖的一棵生成樹然後給出一些其他的邊,沒有重邊和自環,問在取且僅取一條樹邊的前提下,圖的最小割邊的數量是多少
解題思路:num維護每個子樹與外界的相連邊的數量,對於每個非樹枝邊,每加一條其最近公共祖先的num值就要-2,最後用棧統計一下就可以了
*/
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <algorithm>
#include <stack>
using namespace std;
const int inf=0x3f3f3f3f;
const int maxn=111111;
const int maxm=411111;
int n,m,num[maxn],du[maxn],fa[maxn];
struct note
{
int v;
int w;
int next;
};
struct SGRAPH
{
int head[maxn],ip;
note edge[maxm];
void init()
{
memset(head,-1,sizeof(head));
ip=0;
}
void addedge(int u,int v,int c)
{
edge[ip].v=v,edge[ip].w=c,edge[ip].next=head[u],head[u]=ip++;
}
int d[maxn][20];
void makeRmqIndex(int A[],int n){
for(int i=1;i<=n;i++) d[i][0]=i;
for(int j=1;(1<<j)<=n;j++)
for(int i=1;i+(1<<j)-1<=n;i++)
d[i][j] = A[d[i][j-1]] < A[d[i+(1<<(j-1))][j-1]]? d[i][j-1]:d[i+(1<<(j-1))][j-1];
}
int rmqIndex(int L,int R,int A[])
{
int k=0;
while ((1<<(k+1))<=R-L+1) k++;
return A[d[L][k]]<A[d[R-(1<<k)+1][k]]? d[L][k]:d[R-(1<<k)+1][k];
}
//---------------------
int E[maxn*2],R[maxn],D[maxn*2],mn;
void dfs(int u,int p,int d){
E[++mn]=u;
D[mn]=d;
R[u]=mn;
fa[u]=p;
for (int i=head[u];i!=-1;i=edge[i].next){
int v=edge[i].v;
if (v==p) continue;
du[u]++;
dfs(v,u,d+1);
E[++mn]=u;
D[mn]=d;
}
}
void LCA_init(){
mn=0;
memset(R,0,sizeof(R));
dfs(1,-1,1);
makeRmqIndex(D,mn);
//getd(1,-1,0);
}
int LCA(int u,int v){
if (R[u]>=R[v]) return E[rmqIndex(R[v],R[u],D)];
else return E[rmqIndex(R[u],R[v],D)];
}
} solver;
int main()
{
int T,tt=0;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
solver.init();
for(int i=1;i<n;i++)
{
int u,v;
scanf("%d%d",&u,&v);
solver.addedge(u,v,1);
solver.addedge(v,u,1);
}
memset(du,0,sizeof(du));
solver.LCA_init();
memset(num,0,sizeof(num));
for(int i=n;i<=m;i++)
{
int u,v;
scanf("%d%d",&u,&v);
num[u]++;
num[v]++;
int ans=solver.LCA(u,v);
num[ans]-=2;
}
stack<int>st;
for(int i=1;i<=n;i++)
{
if(du[i]==0)st.push(i);
}
while(!st.empty())
{
int v=st.top();
st.pop();
int u=fa[v];
du[u]--;
num[u]+=num[v];
if(du[u]==0&&u>0)
st.push(u);
}
int ans=inf;
for(int i=2;i<=n;i++)
{
//printf("%d::%d\n",i,num[i]);
ans=min(ans,num[i]);
}
printf("Case #%d: %d\n",++tt,ans+1);
}
return 0;
}
相關文章
- 最近公共祖先
- 樹上問題/簡單演算法 LCA【最近公共祖先】演算法
- LeetCode——最近公共祖先LeetCode
- ACM-ICPC 2018 瀋陽賽區網路預賽ACM
- 瀋陽網路賽I-Lattice's basics in digital electronics【模擬】Git
- 二叉樹的最近公共祖先二叉樹
- Git 中的演算法-最近公共祖先Git演算法
- 「學習筆記」tarjan 求最近公共祖先筆記
- 8.3考試總結(NOIP模擬19)[最長不下降子序列·完全揹包問題·最近公共祖先]
- 2018 瀋陽賽區網路預賽 I.Lattice's basics in digital electronics(模擬)Git
- 瀋陽站-出師表
- 瀋陽 李晨陽 閆石 開房門:LED藉助網際網路+新升級
- 演算法學習筆記(5): 最近公共祖先(LCA)演算法筆記
- 【leetcode 簡單】 第六十八題 二叉搜尋樹的最近公共祖先LeetCode
- POJ 1330 LCA最近公共祖先 離線tarjan演算法演算法
- # 劍指 Offer 68 - II. 二叉樹的最近公共祖先二叉樹
- 小瀋陽現象分析
- Google S2 中的四叉樹求 LCA 最近公共祖先Go
- 二叉搜尋樹和二叉樹的最近公共祖先二叉樹
- 立足瀋陽 輻射北區 綠盟科技發出網路安全之聲
- 瀋陽開飛機票行程單行程
- 瀋陽東網科技和福建卓智網路面試心得面試
- 樹上公共祖先(LCA)
- LCA最近公共祖先 線上演算法和離線演算法 模板演算法
- HDU 1330 Nearest Common Ancestors(求兩個點的最近公共祖先)REST
- 236、二叉樹的最近公共祖先 | 演算法(leetcode,附思維導圖 + 全部解法)300題二叉樹演算法LeetCode
- 2023ICPC 瀋陽
- leetcode 235. 二叉搜尋樹的最近公共祖先LeetCode
- 2021網路安全周·瀋陽站 | 綠盟科技威脅情報中心落戶盛京
- 最近思考的一個問題
- ICPC2023瀋陽K
- 面試必考:網路問題面試
- 公司網路有問題
- ICPC2023瀋陽站題解(B C D E I J K M)
- 2013長沙網路賽H題Hypersphere (蛋疼的題目 神似邀請賽A題)
- (117)235. 二叉搜尋樹的最近公共祖先(leetcode)LeetCode
- 2024ccpc網路賽補題
- Google賽馬問題Go