BZOJ1718
重边的存在让我很难受啊。。。。无向图的缩点,记录入度,如果为1就ans++(代码因为统计了两次所以为2就++)
#include<cstdio>
#include<algorithm>
using namespace std;
int head[5005],nxt[20005],to[20005],tot,_tot,num[20005],fa[20005];
int x,y,n,m;
int low[5005],dfn[5005],cnt,belong[5005],tim,stk[5005],top;
void add(int x,int y)
{
to[++tot]=y;nxt[tot]=head[x];head[x]=tot;num[tot]=++_tot;
to[++tot]=x;nxt[tot]=head[y];head[y]=tot;num[tot]=_tot;
}
void tarjan(int u)
{
low[u]=dfn[u]=++tim;
stk[top++]=u;
for(int i=head[u];i;i=nxt[i])
{
if(num[i]==fa[u])
continue;
if(!dfn[to[i]])
{
fa[to[i]]=num[i];
tarjan(to[i]);
low[u]=min(low[to[i]],low[u]);
}
else
{
low[u]=min(dfn[to[i]],low[u]);
}
}
if(low[u]==dfn[u])
{
int k;++cnt;
do
{
k=stk[--top];
belong[k]=cnt;
}while(k!=u);
}
}
bool vis[20005];
int in[5005];
int main()
{
scanf("%d%d",&n,&m);
for(int i=0;i<m;i++)
{
scanf("%d%d",&x,&y);
add(x,y);
}
tarjan(1);
for(int i=1;i<=n;i++)
{
for(int j=head[i];j;j=nxt[j])
{
if(vis[j])
continue;
if(belong[i]==belong[to[j]])
continue;
in[belong[i]]++;
in[belong[to[j]]]++;
vis[j]=1;
}
}
int leaf=0;
for(int i=1;i<=cnt;i++)
{
if(in[i]==2)
leaf++;
}
printf("%d",(leaf+1)>>1);
return 0;
}