POJ 3352 3177 //桥

#include<cstdio>

#include<cstring>

#include<algorithm>

using namespace std;

#define size 5000

struct edge

{

    int to,next;

} e[500000];

int v[size],cnt;

void insert(int from,int to)

{

    e[cnt].to=to;

    e[cnt].next=v[from];

    v[from]=cnt++;

}

int low[size],dfn[size],index;

 

void tarjan(int id,int from)

{

    low[id]=dfn[id]=++index;

    bool flag=false;

    for(int i=v[id];i!=-1;i=e[i].next)

        if(e[i].to==from&&!flag) flag=true;

        else

        {

            if(!dfn[e[i].to]) tarjan(e[i].to,id);

            low[id]=min(low[id],low[e[i].to]);

        }

}

 

void solve(int n)

{

    index=0;

    memset(dfn,0,sizeof(dfn));

    for(int i=0;i<n;i++)

    if(!dfn[i]) tarjan(i,-1);

}

int r,f,a,b,ans[size];

int main()

{

    while(scanf("%d%d",&f,&r)!=EOF)

    {

        memset(v,-1,sizeof(v));

        cnt=0;

        while(r--)

        {

            scanf("%d%d",&a,&b);

            insert(a-1,b-1);

            insert(b-1,a-1);

        }

        solve(f);

        memset(ans,0,sizeof(ans));

        int re=0;//用tarjan的变形算法求出low数组,low相同的点就在一个边连通分量中

        for(int i=0;i<f;i++)

            for(int j=v[i];j!=-1;j=e[j].next)

            if(low[i]!=low[e[j].to]) ans[low[i]]++;

        for(int i=0;i<=f;i++) if (ans[i]==1) re++;

        printf("%d/n",(re+1)/2);

    }

    return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值