hdu5452 Minimum Cut(弱数据)

题目

Minimum Cut
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


思路:

沈阳站网赛一次A,很有成就感啊,尤其在通过率那么高的情况下~~~
题目要求删除最少的边使得G图变得不连通,其中一条边属于G的生成树T,问最少删几条边。
记td为点在树上的度,gd为点在图上的度。因为要删一条生成树上的边使图不连通,则点在树上的度为1的这个点才可以删,否则删掉了一条在树上的边,这个点仍在图的生成树上,无论怎么删图上的边,这个图都不会不连通。那么,筛出来在树上度为1的点集,在里面找在图上的度最小的点相加即是结果。


代码

#include<iostream>
#include<fstream>
#include<string>
#include<algorithm>
#include<math.h>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<vector>
#include<stdio.h>
#include<stdlib.h>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>

using namespace std;

typedef long long LL;
typedef long double real;
typedef vector<int> VI;


#define mems0(s)  memset(s,0,sizeof(s))
#define mems_1(s) memset(s,-1,sizeof(s))
#define memsINF(s) memset(s,INF,sizeof(s))

#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1


/**************************************************************
    Problem: hdu5452Minimum Cut
    Ordering: 图论
    Thought: 点在树上的度为1的点找点在图上度最小的点
    Result: Accepted
    Author: wygdove
****************************************************************/


const double eps = 1e-9;
const double pi=acos(-1.0);
#define INF 0x3f3f3f3f
#define MINN -0x3f3f3f3f
#define MAXN 0x3f3f3f3f
#define MOD 10007
#define NUM 20008

int td[NUM];
int gd[NUM];
bool vis[NUM];

int main()
{
    cin.sync_with_stdio(false);
    cout.sync_with_stdio(false);

    //freopen("mu.in","r",stdin);
    //freopen("out.out","w",stdout);

    int T;
    int n,m;
    int a,b;
    int ans;
    scanf("%d",&T);
    for(int cnt=1;cnt<=T;cnt++)
    {
        mems0(td);
        mems0(gd);
        mems0(vis);

        scanf("%d%d",&n,&m);
        for(int i=0;i<n-1;i++)
        {
            scanf("%d%d",&a,&b);
            td[a]++;td[b]++;
            if(td[a]>1)vis[a]=1;
            if(td[b]>1)vis[b]=1;
        }
        for(int i=0;i<m-n+1;i++)
        {
            scanf("%d%d",&a,&b);
            gd[a]++;gd[b]++;
        }
        ans=INF;
        for(int i=1;i<=n;i++)
        {
            if(!vis[i])
                ans=ans<(td[i]+gd[i])?ans:(td[i]+gd[i]);
        }
        printf("Case #%d: %d\n",cnt,ans);

    }

    fclose(stdin);
    fclose(stdout);
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

posted @ 2015-09-21 13:52  wygdove  阅读(334)  评论(0编辑  收藏  举报