码迷,mamicode.com
首页 > 其他好文 > 详细

Vijos P1325桐桐的糖果计划(有向图双连通分量)

时间:2016-08-24 07:40:31      阅读:194      评论:0      收藏:0      [点我收藏+]

标签:

/*重边不能删 不能删 不能删...*/
#include<iostream>
#include<cstdio>
#include<cstring>
#define maxn 10010
using namespace std;
int n,m,num,head[maxn],low[maxn],dfn[maxn],topt;
int top,s[maxn],f[maxn],ans,sum,belong[maxn],r[maxn];
struct node{int v,pre;}e[maxn*2];
void Add(int from,int to)
{
    /*for(int i=head[from];i;i=e[i].pre)
      if(e[i].v==to)return;*/
    e[num].v=to;
    e[num].pre=head[from];
    head[from]=num++;
}
void Dfs(int x,int fa)
{
    low[x]=dfn[x]=++topt;
    s[++top]=x;f[x]=1;
    for(int i=head[x];i!=-1;i=e[i].pre)
      {
          int v=e[i].v;
          if(i==(fa^1))continue;
          if(dfn[v]==0)
            {
                Dfs(v,i);
                low[x]=min(low[x],low[v]);
                if(low[v]>dfn[x])ans++;
          }
        else if(f[v])
          low[x]=min(low[x],dfn[v]);
      }
    if(low[x]==dfn[x])
      {
          sum++;
          while(x!=s[top])
            {
                belong[s[top]]=sum;f[s[top]]=0;top--;
          }
        belong[s[top]]=sum;f[s[top]]=0;top--;
      }
}
int main()
{
    scanf("%d%d",&n,&m);
    int u,v;
    memset(head,-1,sizeof(head));
    for(int i=1;i<=m;i++)
      {
          scanf("%d%d",&u,&v);
          Add(u,v);Add(v,u);
      }
    for(int i=1;i<=n;i++)
      if(dfn[i]==0)
        Dfs(i,-1);
    printf("%d\n",ans);ans=0;
    for(int u=1;u<=n;u++)
      for(int i=head[u];i!=-1;i=e[i].pre)
        {
          int v=e[i].v;
          if(belong[u]!=belong[v])
            r[belong[u]]++;
        }
    for(int i=1;i<=sum;i++)
      if(r[i]==1)ans++;
    printf("%d\n",(ans+1)/2);
}

 

Vijos P1325桐桐的糖果计划(有向图双连通分量)

标签:

原文地址:http://www.cnblogs.com/yanlifneg/p/5801440.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!