poj 3352Road Construction(无向强连通分量 tarjan)
来源:互联网 发布:严歌苓 知乎 编辑:程序博客网 时间:2024/04/30 20:48
Description
It's almost summer time, and that means that it's almost summer construction time! This year, the good people who are in charge of the roads on the tropical island paradise of Remote Island would like to repair and upgrade the various roads that lead between the various tourist attractions on the island.
The roads themselves are also rather interesting. Due to the strange customs of the island, the roads are arranged so that they never meet at intersections, but rather pass over or under each other using bridges and tunnels. In this way, each road runs between two specific tourist attractions, so that the tourists do not become irreparably lost.
Unfortunately, given the nature of the repairs and upgrades needed on each road, when the construction company works on a particular road, it is unusable in either direction. This could cause a problem if it becomes impossible to travel between two tourist attractions, even if the construction company works on only one road at any particular time.
So, the Road Department of Remote Island has decided to call upon your consulting services to help remedy this problem. It has been decided that new roads will have to be built between the various attractions in such a way that in the final configuration, if any one road is undergoing construction, it would still be possible to travel between any two tourist attractions using the remaining roads. Your task is to find the minimum number of new roads necessary.
Input
The first line of input will consist of positive integers n and r, separated by a space, where 3 ≤ n ≤ 1000 is the number of tourist attractions on the island, and 2 ≤ r≤ 1000 is the number of roads. The tourist attractions are conveniently labelled from 1 to n. Each of the following r lines will consist of two integers, v and w, separated by a space, indicating that a road exists between the attractions labelled v and w. Note that you may travel in either direction down each road, and any pair of tourist attractions will have at most one road directly between them. Also, you are assured that in the current configuration, it is possible to travel between any two tourist attractions.
Output
One line, consisting of an integer, which gives the minimum number of roads that we need to add.
Sample Input
Sample Input 110 121 21 31 42 52 65 63 73 87 84 94 109 10Sample Input 23 31 22 31 3
Sample Output
Output for Sample Input 12Output for Sample Input 20
题意:
某个企业想把一个热带天堂岛变成旅游胜地,岛上有N个旅游景点,任意2个旅游景点之间有路径连通(注意不一定是直接连通)。而为了给游客提供更方便的服务,该企业要求道路部门在某些道路增加一些设施。
道路部门每次只会选择一条道路施工,在该条道路施工完毕前,其他道路依然可以通行。然而有道路部门正在施工的道路,在施工完毕前是禁止游客通行的。这就导致了在施工期间游客可能无法到达一些景点。
为了在施工期间所有旅游景点依然能够正常对游客开放,该企业决定搭建一些临时桥梁,使得不管道路部门选在哪条路进行施工,游客都能够到达所有旅游景点。给出当下允许通行的R条道路,问该企业至少再搭建几条临时桥梁,才能使得游客无视道路部门的存在到达所有旅游景点?
就是给你一个无向图问至少添加几条边就成了强连通图
思路:
1、 首先要找出图G的所有【边双连通分量】
2、把每一个【边双连通分量】都看做一个点(即【缩点】)
3、 问题再次被转化为“至少在缩点树上增加多少条树边,使得这棵树变为一个双连通图”。
首先知道一条等式:
若要使得任意一棵树,在增加若干条边后,变成一个双连通图,那么
至少增加的边数 =( 这棵树总度数为1的结点数 + 1 )/ 2
4、 求出所有缩点的度数的方法
两两枚举图G的直接连通的点,只要这两个点不在同一个【缩点】中,那么它们各自所在的【缩点】的度数都+1。注意由于图G时无向图,这样做会使得所有【缩点】的度数都是真实度数的2倍,必须除2后再判断叶子
#include <stdio.h>#include <string.h>#define Max 10001//建图struct Edge{ int to; int next;} edge[Max*5];int head[Max],tol;void add(int a, int b){ edge[tol].to = b; edge[tol].next = head[a]; head[a] = tol++;}//tarjanint Belong[Max];//表示i在第几个强连通分量int dfn[Max];//时间戳,也就是i是第几个访问的int low[Max];//该节点及其子节点到达最小的dfnint Stack[Max];//储存访问节点bool instack[Max];//判断该节点是不是在栈里面int out[Max];//看连通分量的出度int Bcnt,time,top;//Bcnt 记录联通块的个数//time 记录访问的次序//top栈顶void tarjan(int u,int fa)//无向连通{ int v; dfn[u] = low[u] = ++time;//初始low[u] = dfn[u]; Stack[top++] = u;// instack[u] = true; bool flag = 1; for( int i = head[u]; i != -1; i = edge[i].next) { v = edge[i].to; if(flag && v == fa) { flag = 0; continue; } else if(!dfn[v])// 如果v未被访问 则v是u的孩子 { tarjan(v,u); if(low[u] > low[v]) low[u] = low[v]; } else//v被访问过 { if(instack[v] && low[u] > dfn[v]) { low[u] = dfn[v]; } } } if(low[u] == dfn[u])//u为割点 { Bcnt++; do { v = Stack[--top]; instack[v] = false; Belong[v] = Bcnt;//记录v所在的联通快 } while(u!=v); }}int main(){ int n,m; int u,v; while(~scanf("%d%d",&n,&m)) { //建图 tol = 0; memset(head,-1,sizeof(head)); while(m--) { int a,b; scanf("%d%d",&a,&b); add(a,b); add(b,a); } //tarjan memset(dfn, 0, sizeof(dfn)); Bcnt = top = time = 0; tarjan(1,-1); int du[Max]; memset(du,0,sizeof(du)); for( u = 1; u <= n; u++) { for( int i = head[u]; i != -1; i = edge[i].next) { v = edge[i].to; if(Belong[u] != Belong[v]) { du[Belong[u]]++,du[Belong[v]]++; } } }// for( int i = 1; i <= n;i++)// printf("%d : %d\n",i,Belong[i]); int leafnum = 0; for( int i = 1; i <= Bcnt; i++) { if(du[i] == 2) leafnum++; } printf("%d\n",(leafnum+1)/2); } return 0;}
- poj 3352Road Construction(无向强连通分量 tarjan)
- POJ 3352 Road Construction(无向连通图)
- POJ 3352|Road Construction|边双联通分量|Tarjan
- poj 3352 Road Construction(边连通+tarjan+缩点)
- POJ 2186(有向图的强连通分量Tarjan)
- POJ 3352 Road Construction(图论-tarjan)
- poj 3352 Road Construction (tarjan)
- 强连通分量(Tarjan)
- 有向图的强连通分量(tarjan算法)
- 有向图强连通分量Tarjan
- 有向图强连通分量Tarjan
- poj 2117(tarjan 求无向图去掉一点的连通分量)
- POJ 3352 Road Construction 无向图割边 + 缩点
- poj 2553 (tarjan求强连通分量+缩点)
- poj 3180 The Cow Prom(强连通分量 Tarjan)
- poj 1236 Network of Schools(强连通分量 Tarjan)
- POJ-1236 Network of Schools (强连通分量[Tarjan])
- poj 2186 tarjan求强连通分量(模板题)
- Textview的样式改变——SpannableString
- Spine 的纹理打包器(texture packer)
- Android屏幕适配全攻略(最权威的官方适配指导)
- 在Activity里嵌套Fragment
- 寒假篇5-魔法照片
- poj 3352Road Construction(无向强连通分量 tarjan)
- 微信小程序日记——高仿知乎日报
- 欢迎使用CSDN-markdown编辑器
- 8953系列----parse vmlinux
- 第四章高级查询--上机题和经典案例
- 关于安卓手机自带返回键的处理问题
- POJ 2031Building a Space Station(叉积点积的应用 )
- 牙疼怎么办 立刻止疼
- 同步与异步的概念