题目大意:一个图,要求你加入最少的边,使得最后得到的图为一个边双连通分支。所谓的边双连通分支,即不存在桥的连通分支(题目保证数据中任意两点都联通)。

解题思路:先用tarjan算法进行缩点建立DAG图, 然后再进行寻找度为1的点有个数x, 那么需要添加的边即为(x+1)/ 2;

起初这样写, 一直WA,然后发现下面两个数据,发现并不能过。

#include <stdio.h>
#include <set>
#include <vector>
#include <string.h>
#include <algorithm>
using namespace std; const int N = ;
vector<int>G[N];
vector<pair<int, int> >DAG;
int dfn[N], low[N], mk[N];
int tot;
int n, m; void init()
{
tot = ;
DAG.clear();
for(int i=; i<=n; ++ i)
{
mk[i] = ;
G[i].clear();
dfn[i] = low[i] = -;
}
} void tarjan(int u, int f)
{
dfn[u] = low[u] = ++ tot;
for(int i = ; i < G[u].size(); ++ i)
{
int v = G[u][i];
if(dfn[v] == -)
{
tarjan(v, u);
low[u] = min(low[u], low[v]);
if(dfn[u] < low[v])
DAG.push_back(make_pair(low[u], low[v]));
}
else if(v != f)
low[u] = min(low[u], dfn[v]);
}
} void solve()
{
init();
for(int i=; i<=m; ++ i)
{
int u, v;
scanf("%d%d", &u, &v);
G[u].push_back(v);
G[v].push_back(u);
}
tarjan(, -);
for(int i=; i<DAG.size(); ++ i)
{
pair<int, int> S = DAG[i];
mk[S.first] ++, mk[S.second] ++;
}
int ans = ;
for(int i=; i<=n; ++ i)
{
if(mk[i] == )
ans ++;
}
printf("%d\n", (ans + ) / );
} int main()
{
while(scanf("%d%d", &n, &m) != EOF)
solve();
return ;
}

需要特别注意两组数据:

2 2

1 2

1 2

2 1

1 2

答案分别是:

0

1

代码如下:

#include <stdio.h>
#include <set>
#include <vector>
#include <string.h>
#include <algorithm>
using namespace std; const int N = ;
vector<int>G[N];
int dfn[N], low[N], mk[N];
int tot;
int n, m; void init()
{
tot = ;
for(int i=; i<=n; ++ i)
{
mk[i] = ;
G[i].clear();
dfn[i] = low[i] = -;
}
} void tarjan(int u, int f)
{
dfn[u] = low[u] = ++ tot;
for(int i = ; i < G[u].size(); ++ i)
{
int v = G[u][i];
if(dfn[v] == -)
{
tarjan(v, u);
low[u] = min(low[u], low[v]);
}
else if(v != f)
low[u] = min(low[u], dfn[v]);
}
} void solve()
{
init();
for(int i=; i<=m; ++ i)
{
int u, v;
scanf("%d%d", &u, &v);
G[u].push_back(v);
G[v].push_back(u);
}
tarjan(, -);
for(int i = ; i <= n; ++ i)
{
for(int j = ; j < G[i].size(); ++ j)
{
if(low[i] != low[G[i][j]])
mk[low[i]] ++;
}
}
int ans = ;
for(int i = ; i <= n; ++ i)
if(mk[i] == )
ans ++;
printf("%d\n", (ans + ) / );
} int main()
{
while(scanf("%d%d", &n, &m) != EOF)
solve();
return ;
}

最新文章

  1. GMT与UTC简介
  2. [Everyday Mathematics]20150204
  3. ASP.NET MVC 实现AJAX跨域请求的两种方法
  4. 201521123113《Java程序设计》第12周学习总结
  5. Android 各种路径详细说明
  6. 最短路计数——Dijkstra
  7. 卡尔曼滤波(Kalman Filter) ZZ
  8. GinKgoCTF-Misc
  9. vue从入门到女装??:从零开始搭建后台管理系统(二)用vue-docute生成线上文档
  10. 基于接口回调详解JUC中Callable和FutureTask实现原理
  11. sbt使用详解
  12. 【转】Ant与Ivy的安装
  13. (转)tomcat+nginx+redis实现均衡负载、session共享(一)
  14. MySQL数据源在Spring中的配置
  15. platform_driver_probe 函数解析
  16. Mysql优化分页
  17. 西南大学校园网客户端共享网络之路由器开wifi
  18. 范浩强treap 普通平衡树
  19. 题目1010:A + B(字符串拆分)
  20. Invalid bound statement (not found) 问题处理

热门文章

  1. 转--Oracle 审计和测试操作
  2. Embedded database support
  3. Jetty与Tomcat的区别 转
  4. jquery checkbox反复调用attr(&#39;checked&#39;, true/false)只有第一次生效
  5. Hadoop I/O操作原理整理
  6. OAF_JDBC系列2 - 通过JDBC连接SQLSERVER数据库DriverManager.getConnection
  7. .tar.gz文件和.rpm文件的区别
  8. [ActionScritp 3.0] 使用LocalConnection建立通信
  9. rh6安装oracle11g+ASM
  10. CoolTrayIcon4.0