hdu5452(2015沈阳网络赛C题)

来源:互联网 发布:足球卡牌手游 知乎 编辑:程序博客网 时间:2024/04/29 18:11

题意:

给出一个无向图和一个此图的生成树,让我们求一个本图的最小割边集,割边集只包括生成树中的一条边,让割边集的边数最少,输出数目。


思路:

并查集+暴力。


代码:

#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#include <vector>using namespace std;const int maxn = 20005;const int maxm = 400005;struct Node {    int to, next;}e1[maxm], e2[maxm];int head1[maxn], head2[maxn];int tot1, tot2;void add1(int u, int v) {    e1[tot1].to = v;    e1[tot1].next = head1[u];     head1[u] = tot1++;}void add2(int u, int v) {    e2[tot2].to = v;    e2[tot2].next = head2[u];     head2[u] = tot2++;}int n;int vis1[maxn];int num[maxn];int ans;int sum;int vis2[maxn];vector<int> vv[maxn];int fa[maxn];int find(int x) {    if(x == fa[x]) return fa[x];    return fa[x] = find(fa[x]);}void unin(int x, int y) {    int fx = find(x), fy = find(y);    if(fx != fy) {        fa[fy] = fx;    }}void dfs(int u) {    vis1[u] = 1;    bool flag = false;    for(int i = head1[u]; i; i = e1[i].next) {        int v = e1[i].to;        if(!vis1[v]) {            dfs(v);            unin(u, v);            for(int j = 0; j < vv[v].size(); j++) {                if(find(u) != find(vv[v][j])) {                    vv[u].push_back(vv[v][j]);                }            }            flag = true;        }    }    for(int i = head2[u]; i; i = e2[i].next) {        int v = e2[i].to;        if(find(u) != find(v)) {            vv[u].push_back(v);        }    }    if(u == 1) return ;//    printf("u : %d\n", u); //    for(int i = 0; i < vv[u].size(); i++) { //        printf("#%d ", vv[u][i]); //    }puts("");    sum = vv[u].size();    ans = min(ans, sum);}int main() {    int t;    int  m;    scanf("%d",&t);    for(int kase = 1; kase <= t; kase++) {        scanf("%d%d",&n, &m);        for(int i = 1; i <= n; i++) {            vv[i].clear();        }        memset(num, 0, sizeof(num));        memset(vis1, 0, sizeof(vis1));        memset(vis2, 0, sizeof(vis2));        memset(head1, 0, sizeof(head1));        memset(head2, 0, sizeof(head2));        tot1 = 1;        tot2 = 1;        int u, v;        int xx;        for(int i = 1; i <= n -1; i ++) {            scanf("%d%d",&u, &v);            add1(u, v);            add1(v, u);            add2(u, v);            add2(v, u);        }        for(int i = n; i <= m; i++) {            scanf("%d%d",&u, &v);            add2(u, v);            add2(v, u);        }        for(int i = 0; i <= n; i++) {            fa[i] = i;        }        ans = 1000000000;        dfs(1);        printf("Case #%d: %d\n", kase, ans);    }    return 0;}


0 0