POJ 3177 Redundant Paths (双连通)

题目地址:POJ 3177

找出各个双连通分量度数为1的点,然后作为叶子节点,,那么ans=(叶子结点数+1)/2。需要注意的是有重边。

代码如下:

#include <iostream>#include <string.h>#include <math.h>#include <queue>#include <algorithm>#include <stdlib.h>#include <map>#include <set>#include <stdio.h>using namespace std;#define LL long long#define pi acos(-1.0)const int mod=1e9+7;const int INF=0x3f3f3f3f;const double eqs=1e-9;const int MAXN=5000+10;int head[MAXN], Ecnt, deg[MAXN];int low[MAXN], dfn[MAXN], belong[MAXN], indx, top, scc, stk[MAXN];struct node {int u, v, next;} edge[21000];void add(int u, int v){edge[Ecnt].u=u;edge[Ecnt].v=v;edge[Ecnt].next=head[u];head[u]=Ecnt++;}void tarjan(int u, int fa){low[u]=dfn[u]=++indx;stk[++top]=u;for(int i=head[u]; i!=-1; i=edge[i].next) {int v=edge[i].v;if(v==fa) continue ;if(!dfn[v]) {tarjan(v,u);low[u]=min(low[u],low[v]);} else low[u]=min(low[u],dfn[v]);}if(low[u]==dfn[u]) {scc++;while(1) {int v=stk[top–];belong[v]=scc;if(u==v) break;}}}void init(){memset(head,-1,sizeof(head));memset(dfn,0,sizeof(dfn));memset(deg,0,sizeof(deg));Ecnt=indx=top=scc=0;}int main(){int n, m, i, j, u, v, ans, flag;//freopen("1.txt","r",stdin);while(scanf("%d%d",&n,&m)!=EOF) {init();while(m–) {scanf("%d%d",&u,&v);flag=0;for(i=head[u];i!=-1;i=edge[i].next){if(edge[i].v==v){flag=1;break;}}if(flag) continue ;add(u,v);add(v,u);}for(i=1; i<=n; i++) {if(!dfn[i]) tarjan(i,-1);}//printf("%d\n",scc);for(i=0; i<Ecnt; i+=2) {u=edge[i].u;v=edge[i].v;if(belong[u]!=belong[v]) {deg[belong[u]]++;deg[belong[v]]++;}}ans=0;for(i=1; i<=scc; i++) {if(deg[i]==1)ans++;}printf("%d\n",(ans+1)/2);}return 0;}

一个能从别人的观念来看事情,能了解别人心灵活动的人,永远不必为自己的前途担心。

POJ 3177 Redundant Paths (双连通)

相关文章:

你感兴趣的文章:

标签云: