Vijos P1325桐桐的糖果计划(有向图双连通分量)
/*重边不能删 不能删 不能删...*/ #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); }