题目链接:

  Hdu 4612 Warm up

题目描述:

  给一个无向连通图,问加上一条边后,桥的数目最少会有几个?

解题思路:

  题目描述很清楚,题目也很裸,就是一眼看穿怎么做的,先求出来双连通分量,然后缩点重新建图,用bfs求树的直径,直径的长度就是减去桥的数目。

这个题目需要手动扩展,而且手动扩展的话要用C++提交,G++re哭了。

 #include <cstdio>
#include <queue>
#include <cstring>
#include <iostream>
#include <algorithm>
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std; const int maxn = ;
struct node
{
int to, next;
}edge[*maxn], Edge[*maxn];
int vis[maxn], dist[maxn];
int head[maxn], low[maxn], dfn[maxn], id[maxn], Head[maxn];
int stack[maxn], tot, Tot, ntime, top, cnt, Max, end_p; void init ()
{
tot = ntime = top = Tot = cnt = Max = end_p = ;
memset (id, , sizeof(id));
memset (low, , sizeof(low));
memset (dfn, , sizeof(dfn));
memset (head, -, sizeof(head));
memset (stack, , sizeof(stack));
memset (Head, -, sizeof(Head));
}
void Add (int from, int to)
{
Edge[Tot].to = to;
Edge[Tot].next = Head[from];
Head[from] = Tot ++;
}
void add (int from, int to)
{
edge[tot].to = to;
edge[tot].next = head[from];
head[from] = tot ++;
}
void Tarjan (int u, int father)
{
int k = ;
low[u] = dfn[u] = ++ntime;
stack[top++] = u;
for (int i=head[u]; i!=-; i=edge[i].next)
{
int v = edge[i].to;
if (v == father && !k)
{
k ++;
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])
{
cnt ++;
while ()
{
int v = stack[--top];
id[v] = cnt;
if (v == u)
break;
}
}
}
void bfs (int s)
{
queue<int>Q;
int u, v;
memset (vis, ,sizeof(vis));
vis[s] = ;
dist[s] = ;
Q.push(s);
while (!Q.empty())
{
u = Q.front();
Q.pop();
for (int i=Head[u]; i!=-; i=Edge[i].next)
{
v = Edge[i].to;
if (!vis[v])
{
vis[v] = ;
dist[v] = dist[u] + ;
Q.push(v);
if (dist[v] > Max)
{
Max = dist[v];
end_p = v;
}
}
}
}
}
void solve (int n)
{
int sum = ;
Tarjan (, );
for (int i=; i<=n; i++)
for (int j=head[i]; j!=-; j=edge[j].next)
{
int u = id[i];
int v = id[edge[j].to];
if (v != u)
{
Add (u, v);
sum ++;
}
}
sum /= ;
bfs ();
bfs (end_p);
printf ("%d\n", sum - Max);
}
int main ()
{
int n, m;
while (scanf ("%d %d", &n, &m), n+m)
{
init ();
while (m --)
{
int u, v;
scanf ("%d %d", &u, &v);
add (u, v);
add (v, u);
}
solve (n);
}
return ;
}

最新文章

  1. Latch2:Latch和性能
  2. 【Linux】find grep 联合使用 过滤所有子目录、文件
  3. Python 字符串方法详解
  4. 【C#】属性(Attribute)
  5. bootstrap-输入框组
  6. [原创]HTML标签总结!! 第一次画 尚需要改进 多关照
  7. Linux中使用mysqldump对MySQL数据库进行定时备份
  8. cocos2d-x 通过JNI实现c/c++和Android的java层函数互调
  9. PDA开发数据由DB下载至PDA本地
  10. python的小技巧 让你的代码更美观
  11. vim 翻页命令
  12. parallel::ForkManager
  13. cron和crontab命令详解 crontab 每分钟、每小时、每天、每周、每月、每年定时执行 crontab每5分钟执行一次
  14. Python—re模块
  15. python-web自动化-元素定位
  16. 实现Winform 跨线程安全访问UI控件
  17. OO第二次课程总结分析
  18. [leetcode]Reverse Linked List II @ Python
  19. Android WiFi 日志记录(ASSOC_REJECT)
  20. 【转】VMware网络连接模式—桥接、NAT以及仅主机模式的详细介绍和区别

热门文章

  1. 【KMP+最小循环节】F. Cyclic Nacklace
  2. hdu 1166 树状数组模板题
  3. idea使用之maven本地索引更新
  4. 1.spring boot要求最低jdk1.8,平安默认1.6问题,-》安装JDK1.8 2.maven 3.3.3要求最低jdk1.7-&gt;安装jdk 1.8
  5. FlashBuilder 4.7 非正常关闭导致的不能启动的解决的方法
  6. [WebGL入门]五,矩阵的基础知识
  7. [Qt总结篇]终端远程升级client
  8. Canvas: trying to use a recycled bitmap android.graphics.Bitmap@XXX
  9. SpringMVC学习指南-Spring框架
  10. 2015/12/30 Java语法学习