Uva-10972-RevolC FaeLoN

来源:互联网 发布:mysql my.ini配置下载 编辑:程序博客网 时间:2024/05/16 17:31

      这个题应该是求双连通分量,但我一直却弄成了点连通分量,导致一直WA。不过性质想到了,是求连通分量缩点,然后答案是度数为1的点加上度数为0的点的2倍然后再除以2

代码:

#include<cstdio>#include<cstring>#include<iostream>#include<stack>#include<vector>using namespace std;const int maxn=1e3+100;const int maxm=1e6+100;int e,n,m,pnt[maxm],nxt[maxm],head[maxn];int dfs_clock,dfn[maxn],low[maxn],cnt[maxn],bccno[maxn],grades[maxn],bccnt;bool iscut[maxn],isbridge[maxn][maxn];struct Edge{    int u;    int v;    Edge(){}    Edge(int su,int sv)    {        u=su;        v=sv;    }};stack<Edge> s;void AddEdge(int u,int v){    pnt[e]=v;nxt[e]=head[u];head[u]=e++;    pnt[e]=u;nxt[e]=head[v];head[v]=e++;}int DFS(int u,int f){    dfn[u]=low[u]=++dfs_clock;    int child=0;    for(int i=head[u];i!=-1;i=nxt[i])    {        if(!dfn[pnt[i]])        {            s.push(Edge(u,pnt[i]));            child++;            low[u]=min(low[u],DFS(pnt[i],u));            if(low[pnt[i]]>=dfn[u])            {                iscut[u]=true;                isbridge[pnt[i]][u]=isbridge[u][pnt[i]]=1;            }        }        else if(dfn[pnt[i]]<dfn[u]&&pnt[i]!=f)        {            s.push(Edge(u,pnt[i]));            low[u]=min(low[u],dfn[pnt[i]]);        }    }    if(f<0&&child==1)        iscut[u]=0;    return low[u];}void dfs(int u){    for(int i=head[u];i!=-1;i=nxt[i])        if(!bccno[pnt[i]]&&!isbridge[u][pnt[i]])        {            bccno[pnt[i]]=bccnt;            dfs(pnt[i]);        }}void Init(){    e=dfs_clock=bccnt=0;    memset(head,-1,sizeof(head));    memset(dfn,0,sizeof(dfn));    memset(low,0,sizeof(low));    memset(iscut,0,sizeof(iscut));}void solve(){    memset(bccno,0,sizeof(bccno));    memset(grades,0,sizeof(grades));    memset(isbridge,0,sizeof(isbridge));    for(int i=1;i<=n;i++)        if(!dfn[i])            DFS(i,-1);    for(int i=1;i<=n;i++)        if(!bccno[i])        {            bccnt++;            bccno[i]=bccnt;            dfs(i);        }    if(bccnt==1)    {        printf("0\n");        return;    }    for(int u=1;u<=n;u++)        for(int i=head[u];i!=-1;i=nxt[i])            if(bccno[u]!=bccno[pnt[i]])                grades[bccno[pnt[i]]]++;    int ans=0;    for(int i=1;i<=bccnt;i++)    {        if(grades[i]==0)            ans+=2;        if(grades[i]==1)            ans++;    }        printf("%d\n",(ans+1)>>1);}int main(){    while(scanf("%d%d",&n,&m)!=EOF)    {        Init();        for(int i=0;i<m;i++)        {            int u,v;            scanf("%d%d",&u,&v);            AddEdge(u,v);        }        solve();    }    return 0;}


0 0
原创粉丝点击