本文主要是介绍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 (双连通)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!