转载请注明出处:http://blog.csdn.net/vmurder/article/details/42671851
其实我就是觉得原创的访问量比未授权盗版多有点不爽233。。。
裸题只给模板。
tarjan可以实现。
太水不发题解。
代码:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 1010
#define M 2020
using namespace std;
struct KSD
{
int v,next;
}e[M];
int head[N],cnt;
inline void add(int u,int v)
{
e[++cnt].v=v;
e[cnt].next=head[u];
head[u]=cnt;
}
int dfn[N],low[N],n,m;
int id[N],group,d[N];
int ans,edges; // 边-双个数、 桥个数
int stk[N],top;
void tarjan(int x,int p) // 边双连通分量,即无桥。
{
int i,v,temp;
dfn[x]=low[x]=++cnt;
stk[++top]=x;
for(i=head[x];i;i=e[i].next)
{
v=e[i].v;
if(v==p)continue;
if(!dfn[v])
{
tarjan(v,x);
low[x]=min(low[x],low[v]);
}
else low[x]=min(low[x],dfn[v]);
// if(dfn[x]<low[v])edges++; // 桥的数目
}
if(dfn[x]==low[x])
{
group++;
do{
temp=stk[top--];
id[temp]=group;
}while(temp!=x);
}
return ;
}
int main()
{
// freopen("test.in","r",stdin);
int i,j,k;
int a,b,c;
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(head,0,sizeof(head));
memset(dfn,0,sizeof(dfn));
memset(d,0,sizeof(d));
cnt=group=ans=0;
for(i=1;i<=m;i++)
{
scanf("%d%d",&a,&b);
add(a,b),add(b,a);
}
cnt=0;
for(i=1;i<=n;i++)if(!dfn[i])tarjan(i,0);
for(j=1;j<=n;j++)
for(i=head[j];i;i=e[i].next)
if(id[j]!=id[e[i].v])d[id[e[i].v]]++;
for(i=1;i<=n;i++)if(d[i]==1)ans++;
printf("%d\n",ans+1>>1);
}
return 0;
}