标签:个数 head highlight next const cstring add ring ==
1:POJ3353 Road Construction
此题没有重边
#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;
//第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])
//有一条边从J-->e[i].v
//e[i].v的入度加1
d[id[e[i].v]]++;
for(i=1;i<=n;i++)
if(d[i]==1)
ans++;
printf("%d\n",(ans+1)>>1);
}
return 0;
}
标签:个数 head highlight next const cstring add ring ==
原文地址:https://www.cnblogs.com/cutemush/p/12681872.html