转载请注明出处: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; }
时间: 2024-10-10 07:43:52