HDU 5452 Minimun Cut (lca+dfs)

Minimum Cut

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

 

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

 思路:題意是先給一棵樹,然後在加一些無向邊變成一個連通圖,在只允許刪除樹中一條邊的情況下刪除最少邊使圖不連通。

如果光是一棵樹的話只要刪任意一條邊就可以達到目標變成兩個子樹,所以各個點的ans都爲1,後面每來一個邊,都會使此邊相連的兩個點的到LCA上的所有點的ans++,因爲要刪這條新邊兩個子樹纔不連通。

 

代碼:

#include<bits/stdc++.h>
using namespace std;

const int maxn=200010;

struct nod{
    int to,next;
}e[maxn*2];

int deep[maxn];
int ans[maxn];
int fa[maxn];
int head[maxn];
int tot;

void add(int f,int t){
        e[tot].to=t;
        e[tot].next=head[f];
        head[f]=tot++;
}

void dfs(int u,int fath,int dp){
    deep[u]=dp;
    ans[u]=1;
    fa[u]=fath;
    for(int i=head[u];i!=-1;i=e[i].next){
        int v=e[i].to;
        if(v!=fath){
            dfs(v,u,dp+1);
        }
    }
}

void lca(int x,int y){
    while(x!=y){
        if(deep[x]>=deep[y]){
            ans[x]++;
            x = fa[x];
        }
        else {
            ans[y]++;
            y=fa[y];
        }
    }
}

int main(){
        int  t,n,m,l;
        scanf("%d",&t);
        int cas=0;
        while(t--){
            tot=0;///init
            memset(head,-1,sizeof(head));
            scanf("%d%d",&n,&m);
            int u,v;
            for(int i=1;i<n;i++) {
                scanf("%d%d",&u,&v);
                add(u,v);
                add(v,u);
            }

            dfs(1,0,1);

            for(int i=n;i<=m;i++) {
                scanf("%d%d",&u,&v);
                lca(u,v);
            }

            int res=0x3f3f3f3f;
            for(int i=2;i<=n;i++) res=min(res,ans[i]);

            printf("Case #%d: %d\n",++cas,res);
        }
}

參考博客:http://www.cnblogs.com/alihenaixiao/p/4828485.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章