ZOJ 2588 Burning Bridges 求割边

注意:去掉反向边

View Code
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define maxn 10004
#define maxm 100055
#define inf 1000000000

int min(int a, int b)
{
    return a < b ? a : b;
}

struct E
{
    int v, next;
}edge[maxm<<1];

int head[maxn], tot;
int n, m;

void add(int s, int t)
{
    edge[tot].v = t;
    edge[tot].next = head[s];
    head[s] = tot++;

    edge[tot].v = s;
    edge[tot].next = head[t];
    head[t] = tot++;
}

int low[maxn], dfn[maxn];
int ans[maxn];
int num;

void init()
{
    tot = 0;
    num = 0;
    memset(head, -1, sizeof(head));
    memset(dfn, 0, sizeof(dfn));
}

int id;
void dfs(int u, int fa)
{
    low[u] = dfn[u] = ++id;
    int i, v;
    bool flag = 0;
    for(i = head[u]; i != -1; i = edge[i].next)
    {
        v = edge[i].v;
        if(!flag && v == fa) { flag = 1; continue; } // 注意:去掉一条反向边, 其它的边可能是重边
        if(!dfn[v])
        {
            dfs(v, u);
            low[u] = min(low[u], low[v]);
            if(low[v] > dfn[u])
                ans[num++] = i; // 边的编号
        }
        else low[u] = min(low[u], dfn[v]);
    }
}

int main()
{
    int i, j, cas;
    int x, y;
    scanf("%d", &cas);
    while(cas--)
    {
        scanf("%d%d", &n, &m);
        init();
        while(m--)
        {
            scanf("%d%d", &x, &y);
            add(x, y);
        }
        dfs(1, -1);
        printf("%d\n", num);
        if(num)
        {
            sort(ans, ans+num);
            for(i = 0; i < num-1; i++)
                printf("%d ", ans[i]/2+1); 
            printf("%d\n", ans[i]/2+1);
        }
        if(cas) puts("");
    }
    return 0;
}

 

 

posted @ 2012-11-01 20:57  To be an ACMan  Views(177)  Comments(0)    收藏  举报