hdu3394Railway

来源:互联网 发布:logo设计软件app 编辑:程序博客网 时间:2024/06/06 20:11

链接:http://acm.hdu.edu.cn/showproblem.php?pid=3394

题意:给定一个n个点m条无向边的图。求有多少个桥以及有多少条边会在两个环中。

分析:点双联通分量的题,桥就是割边,冲突边就是一个点联通分量中边>点就是啦。

代码:

#include<map>#include<set>#include<stack>#include<cmath>#include<queue>#include<bitset>#include<math.h>#include<vector>#include<string>#include<stdio.h>#include<cstring>#include<iostream>#include<algorithm>#pragma comment(linker, "/STACK:102400000,102400000")using namespace std;typedef double db;typedef long long ll;typedef unsigned int uint;typedef unsigned long long ull;const db eps=1e-5;const int N=1e4+10;const int M=2e5+10;const ll MOD=1000000007;const int mod=1000000007;const int MAX=1000000010;const double pi=acos(-1.0);int tot,u[N],v[M],pre[M];void add(int a,int b) {    v[tot]=b;pre[tot]=u[a];u[a]=tot++;    v[tot]=a;pre[tot]=u[b];u[b]=tot++;}struct Edge{    int u,v;    Edge(int u,int v):u(u),v(v){}};stack<Edge>S;int ans1,ans2;int bcc_cnt,dfs_clock,first[N],bccno[N];int dfs_bcc(int a,int b) {    int i,j,lowa,lowv,now,B,D;    first[a]=lowa=++dfs_clock;    for (i=u[a];~i;i=pre[i])    if (v[i]!=b) {        Edge e=Edge(a,v[i]);        if (!first[v[i]]) {            S.push(e);            lowv=dfs_bcc(v[i],a);            lowa=min(lowa,lowv);            if (lowv>=first[a]) {                if (lowv>first[a]) ans1++;                bcc_cnt++;B=D=0;                while (1) {                    Edge x=S.top();S.pop();B++;                    if (bccno[x.u]!=bcc_cnt) bccno[x.u]=bcc_cnt,D++;                    if (bccno[x.v]!=bcc_cnt) bccno[x.v]=bcc_cnt,D++;                    if (x.u==a&&x.v==v[i]) break ;                }                if (B>D) ans2+=B;            }        } else if (first[v[i]]<first[a]) {                S.push(e);                lowa=min(lowa,first[v[i]]);            }    }    return lowa;}int main(){    int a,b,i,n,m;    while (scanf("%d%d", &n, &m)&&n) {        for (tot=0,i=0;i<n;i++) u[i]=-1;        for (i=0;i<m;i++) scanf("%d%d", &a, &b),add(a,b);        ans1=ans2=bcc_cnt=dfs_clock=0;        for (i=0;i<n;i++) first[i]=bccno[i]=0;        for (i=0;i<n;i++)        if (!first[i]) dfs_bcc(i,-1);        printf("%d %d\n", ans1, ans2);    }    return 0;}


0 0