hdu 4612 Warm up(无向图Tarjan+树的直径)
题意:有N个点,M条边(有重边)的无向图,这样图中会可能有桥,问加一条边后,使桥最少,求该桥树。
思路:这个标准想法很好想到,缩点后,求出图中的桥的个数,然后重建图必为树,求出树的最长直径,在该直径的两端点连一边,则图中的桥会最少。
从这题中学到两点,所以写一下解题报告。
1.官方说judge的栈小,得手动增栈 #pragma comment(linker,"/STACK:102400000,102400000") 以前没见过,算是学习了。
2.对改正了对Tarjan算法的一个错误理解,以前看某人博客说,无向图中,Tarjan后low值相等的点属于同一块,以前这样判断过,也过了挺多题。但跟别人讨论后发现是错的。。。。。
3.以前没用Tarjan写过无向图,不懂正向边访问过,标志反向边,这次学习了。
//937MS 41304K
#pragma comment(linker, "/STACK:102400000,102400000")
#include
#include
const int VM = 200005;
const int EM = 1000005; struct Edeg
{
int to,nxt,vis;
}edge[EM<<1],tree[EM<<1]; int head[VM],vis[VM],thead[VM];
int dfn[VM],low[VM],stack[VM],belong[VM];
int ep,bridge,son,maxn,src,n,cnt,scc,top; int max (int a,int b)
{
return a > b ? a : b;
}
int min(int a ,int b)
{
return a > b ? b : a;
}
void addedge (int cu,int cv)
{
edge[ep].to = cv;
edge[ep].vis = 0;
edge[ep].nxt = head[cu];
head[cu] = ep ++;
edge[ep].to = cu;
edge[ep].vis = 0;
edge[ep].nxt = head[cv];
head[cv] = ep ++;
}
void Buildtree(int cu,int cv)
{
tree[son].to = cv;
tree[son].nxt = thead[cu];
thead[cu] = son ++;
}
void Tarjan (int u)
{
int v;
vis[u] = 1;
dfn[u] = low[u] = ++cnt;
stack[top++] = u;
for (int i = head[u];i != -1;i = edge[i].nxt)
{
v = edge[i].to;
if (edge[i].vis) continue; //
edge[i].vis = edge[i^1].vis = 1; //正向边访问过了,反向边得标志,否则两点会成一块。
if (vis[v] == 1)
low[u] = min(low[u],dfn[v]);
if (!vis[v])
{
Tarjan (v);
low[u] = min(low[u],low[v]);
if (low[v] > dfn[u])
bridge ++;
}
}
if (dfn[u] == low[u])
{
++scc;
do{
v = stack[--top];
vis[v] = 0;
belong[v] = scc;
}while (u != v);
}
}
void BFS(int u)
{
int que[VM+100];
int front ,rear,i,v;
front = rear = 0;
memset (vis,0,sizeof(vis));
que[rear++] = u;
vis[u] = 1;
while (front != rear)
{
u = que[front ++];
front = front % (n+1);
for (i = thead[u];i != -1;i = tree[i].nxt)
{
v = tree[i].to;
if (vis[v]) continue;
vis[v] = 1;
que[rear++] = v;
rear = rear%(n+1);
}
}
src = que[--rear];//求出其中一个端点
}
void DFS (int u,int dep)
{
maxn = max (maxn,dep);
vis[u] = 1;
for (int i = thead[u]; i != -1; i = tree[i].nxt)
{
int v = tree[i].to;
if (!vis[v])
DFS (v,dep+1);
}
}
void solve()
{
int u,v;
memset (vis,0,sizeof(vis));
cnt = bridge = scc = top = 0;
Tarjan (1);
memset (thead,-1,sizeof(thead));
son = 0;
for (u = 1;u <= n;u ++) //重构图
for (int i = head[u];i != -1;i = edge[i].nxt)
{
v = edge[i].to;
if (belong[u]!=belong[v])
{
Buildtree (belong[u],belong[v]);
Buildtree (belong[v],belong[u]);
}
}
maxn = 0; //最长直径
BFS(1); //求树直径的一个端点
memset (vis,0,sizeof(vis));
DFS(src,0); //求树的最长直径
printf ("%d\n",bridge-maxn);
} int main ()
{
#ifdef LOCAL
freopen ("in.txt","r",stdin);
#endif
int m,u,v;
while (~scanf ("%d%d",&n,&m))
{
if (n == 0&&m == 0)
break;
memset (head,-1,sizeof(head));
ep = 0;
while (m --)
{
scanf ("%d%d",&u,&v);
addedge (u,v);
}
solve();
}
return 0;
}
hdu 4612 Warm up(无向图Tarjan+树的直径)的更多相关文章
- 【HDU 4612 Warm up】BCC 树的直径
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4612 题意:一个包含n个节点m条边的无向连通图(无自环,可能有重边).求添加一条边后最少剩余的桥的数 ...
- Hdu 4612 Warm up (双连通分支+树的直径)
题目链接: Hdu 4612 Warm up 题目描述: 给一个无向连通图,问加上一条边后,桥的数目最少会有几个? 解题思路: 题目描述很清楚,题目也很裸,就是一眼看穿怎么做的,先求出来双连通分量,然 ...
- HDU 4612——Warm up——————【边双连通分量、树的直径】
Warm up Time Limit:5000MS Memory Limit:65535KB 64bit IO Format:%I64d & %I64u Submit Stat ...
- hdu 4612 Warm up 有重边缩点+树的直径
题目链接 Warm up Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)Tot ...
- HDU 4612 Warm up —— (缩点 + 求树的直径)
题意:一个无向图,问建立一条新边以后桥的最小数量. 分析:缩点以后,找出新图的树的直径,将这两点连接即可. 但是题目有个note:两点之间可能有重边!而用普通的vector保存边的话,用v!=fa的话 ...
- HDU 4612 Warm up(双连通分量缩点+求树的直径)
思路:强连通分量缩点,建立一颗新的树,然后求树的最长直径,然后加上一条边能够去掉的桥数,就是直径的长度. 树的直径长度的求法:两次bfs可以求,第一次随便找一个点u,然后进行bfs搜到的最后一个点v, ...
- HDU 4612 Warm up (边双连通分量+缩点+树的直径)
<题目链接> 题目大意:给出一个连通图,问你在这个连通图上加一条边,使该连通图的桥的数量最小,输出最少的桥的数量. 解题分析: 首先,通过Tarjan缩点,将该图缩成一颗树,树上的每个节点 ...
- hdu 4612 Warm up
http://acm.hdu.edu.cn/showproblem.php?pid=4612 将原图进行缩点 变成一个树 树上每条边都是一个桥 然后加一条边要加在树的直径两端才最优 代码: #incl ...
- HDU 4612 Warm up(2013多校2 1002 双连通分量)
Warm up Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)Total Su ...
随机推荐
- 在JS中调用JAVA变量
在JS中调用JAVA变量可以,方法是:var JS变量名 = “<%=JAVA变量名 %>”<%中间写java代码,跟在JSP中一样%>在JAVA中 ,无法调用JS变量
- entity framework 6 通用数据类
原文 http://blog.csdn.net/laokaizzz/article/details/25730813 public class BaseDAL { string strConn = ...
- oracle的nvl和sql server的isnull函数
最近公司在做Oracle数据库相关产品,在这里作以小结: ISNULL()函数 语法 ISNULL ( check_expression , replacement_value) 参数 ...
- PHP 获取客户端IP
function get_ip() { static $realIP; if (isset($_SERVER)){ if (isset($_SERVER["HTTP_X_FORWARDED_ ...
- Yii 安装
// 安装 composer curl -s http://getcomposer.org/installer | php // 把 composer 添加到全局命令 mv composer.phar ...
- python对真假的判断方式
一.如下是以下值就认为是假 1.None-->None值 2.False-->False值 3.0-->数值零不管它是int,float还是complex类型 4.'',(),[]- ...
- 给FPGA初学者的建议——不要浮躁(转)
原作者:http://hi.baidu.com/zhoubin7020 作为FPGA新人常常在论坛上问,用什么语言啊,用什么软件啊,用那个公司的芯片等问题.我个人认为学习FPGA和学习单片机有相同的道 ...
- javascript之尺寸,位置,溢出
一.offsetWidth:元素的宽度,包括边框,内容,内边距. 二.offsetHeight:元素的高度,包括边框,内容,内边距. 三.offsetLeft:元素的X坐标(相对于最近已定位的祖先元素 ...
- HttpRuntime类
HttpRuntime在ASP.NET处理请求中负责的是创建HttpContext对象以及调用HttpApplicationFactory创建HttpApplication. 其定义如下: publi ...
- Apache、php、mysql单独安装配置
php, 安装版的,http://www.php.net/manual/zh/install.php.也有不安装版直接配置的. 在Windows 7下如何进行PHP配置环境. PHP环境在Window ...