大致题意:
某个企业想把一个热带天堂岛变成旅游胜地,岛上有N个旅游景点,任意2个旅游景点之间有路径连通(注意不一定是直接连通)。而为了给游客提供更方便的服务,该企业要求道路部门在某些道路增加一些设施。
道路部门每次只会选择一条道路施工,在该条道路施工完毕前,其他道路依然可以通行。然而有道路部门正在施工的道路,在施工完毕前是禁止游客通行的。这就导致了在施工期间游客可能无法到达一些景点。
为了在施工期间所有旅游景点依然能够正常对游客开放,该企业决定搭建一些临时桥梁,使得不管道路部门选在哪条路进行施工,游客都能够到达所有旅游景点。给出当下允许通行的R条道路,问该企业至少再搭建几条临时桥梁,才能使得游客无视道路部门的存在到达所有旅游景点?
至少增加的边数 =( 这棵树总度数为1的结点数 + 1 )/ 2
参考资料:http://blog.csdn.net/lyy289065406/article/details/6762370
https://www.byvoid.com/blog/biconnect/
#include <iostream> #include <stdio.h> using namespace std; #define MAXV 5010 #define min(a,b) (a>b?b:a) int n,m; bool map[MAXV][MAXV]; bool vis[MAXV]; int low[MAXV],dfn[MAXV]; int count; int cnt[MAXV]; void init(){ memset(vis,0,sizeof(vis)); memset(low,0,sizeof(low)); memset(dfn,0,sizeof(dfn)); count=0; } void dfs(int x,int pre){ int i; vis[x]=1; low[x]=dfn[x]=++count; for(i=1;i<=n;i++){ if(map[x][i]){ if(!vis[i]){ dfs(i,x); low[x]=min(low[x],low[i]); } if(vis[i]==1 && i!=pre){ low[x]=min(low[x],dfn[i]); } } } } int main(){ int a,b; int i,j; while(~scanf("%d%d",&n,&m)){ memset(map,0,sizeof(map)); while(m--){ scanf("%d%d",&a,&b); map[a][b]=map[b][a]=1; } init(); dfs(1,1); memset(cnt,0,sizeof(cnt)); for(i=1;i<=n;i++){ //计算每个点的度 for(j=1;j<=n;j++) if(map[i][j]){ if(low[i]!=low[j]){ cnt[low[j]]++; } } } int ans=0; //计算度为1的点的个数 for(i=1;i<=n;i++){ if(cnt[i]==1) ans++; } printf("%d\n",(ans+1)/2); } return 0; }