列表

详情


NC23052. 华华和月月逛公园

描述

月月和华华一起去逛公园了。公园很大,为了方便,可以抽象的看成一个N个点M条边的无向连通图(点是景点,边是道路)。公园唯一的入口在1号点,月月和华华要从这里出发,并打算参观所有的景点。因为他们感情很好,走多远都不会觉得无聊,所以所有景点和道路都可以无数次的重复经过。月月发现,有些路可走可不走,有些路则必须要走,否则就无法参观所有的景点。现在月月想知道,有几条路是不一定要经过的。因为这是个很正常的公园,所以没有重边和自环。

输入描述

第一行两个正整数N和M,表示点数和边数。
接下来M行,每行两个正整数U和V表示一条无向边。
保证给定的图是连通的。

输出描述

输出一行一个非负整数表示不一定要经过的边有几条。

示例1

输入:

5 5
1 2
2 3
3 4
4 5
3 5

输出:

3

说明:

例如第三条边,月月和华华可以依次走过第一条、第二条、第五条、第四条边走过全部的景点,所以第三条边不一定要经过。同理还有第四条、第五条边,答案为3。

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 230ms, 内存消耗: 14720K, 提交时间: 2019-03-09 22:10:29

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
vector<int>G[maxn];
int cnt,res,low[maxn],dfn[maxn];
void dfs(int u,int fa)
{
	dfn[u]=low[u]=++cnt;
	for(int i=0;i<G[u].size();i++)
	{
		int v=G[u][i];
		if(v==fa)continue;
		if(!dfn[v])
		{
			dfs(v,u);
			low[u]=min(low[u],low[v]);
			if(low[v]>dfn[u])
			res++;
		}
		else
		low[u]=min(low[u],dfn[v]);
	}
}
int main()
{
	int n,m,u,v;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d",&u,&v);
		G[u].push_back(v);
		G[v].push_back(u);
	}
	dfs(1,0);
	printf("%d\n",m-res);
}

C++11(clang++ 3.9) 解法, 执行用时: 181ms, 内存消耗: 15588K, 提交时间: 2020-01-11 11:06:18

#include<bits/stdc++.h>
using namespace std;

int s=0,c=0,dfn[100005],low[100005];
vector<int>R[100005];
void tarjan(int x,int fa)
{
	int i,j;
	dfn[x]=low[x]=++c;
	for(i=0;i<R[x].size();i++)
	{
		j=R[x][i];
		if(!dfn[j])
		{
			tarjan(j,x);
			low[x]=min(low[x],low[j]);
			if(low[j]>dfn[x])s++;
		}
		else if(j!=fa)low[x]=min(low[x],dfn[j]);
	}
}
int main()
{
	int i,j,k,N,M;
	scanf("%d%d",&N,&M);
	for(i=0;i<M;i++)scanf("%d%d",&j,&k),R[j].push_back(k),R[k].push_back(j);
	tarjan(1,0);
	printf("%d\n",M-s);
	return 0;
}

上一题