题意:在连通图中,求一条边使得加入这条边以后的消除的桥尽量多。

在同一个边双连通分量内加边肯定不会消除桥的,

求边双连通分量以后缩点,把桥当成边,实际上是要选一条最长的链。

缩点以后会形成一颗树,一定不存在环否则和桥的定义矛盾,求树上的最远点对。

树上的最远点对用dp TLE了,实际上两次dfs就行了,第一次随便选一个点dfs找到最远的点,

再从那个点dfs找最远的点就是树上的最远点对,为什么这样是对的呢?反向来构造,假设已经找了最长的链,

往链上某点上添加一条链,这条链的长度一定小于这个点到两个端点之中距离的最小的那个,

因此无论从哪个点出发dfs,一定会到达最长的链的一个端点。第二遍就一定能找到最长的链。

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e4+, maxm = 2e5+;
int head[maxn],nxt[maxm],to[maxm],ecnt; void addEdge(int u,int v)
{
to[ecnt] = v;
nxt[ecnt] = head[u];
head[u] = ecnt++;
} int pre[maxn],low[maxn],dfs_clock;
bool cut[maxm]; void tarjan(int u,int fa)
{
pre[u] = low[u] = ++dfs_clock;
for(int i = head[u]; ~i; i = nxt[i]){
int v = to[i];
if(!pre[v]){
tarjan(v,i);
low[u] = min(low[u],low[v]);
if(low[v] > pre[u]){
//if(fa<0) cut[i] = cut[i^1] = ~nxt[head[u]];
//else
cut[i] = cut[i^] = true;
}
}else if( (i^)!=fa && pre[v] < pre[u]){
low[u] = min(pre[v],low[u]);
}
}
} int eccno[maxn],ecc_cnt;
int pid[maxn];
void dfs(int u)
{
eccno[u] = ecc_cnt;
for(int i = head[u]; ~i; i = nxt[i] ) if(!cut[i]){
if(!eccno[to[i]]) dfs(to[i]);
}
} vector<int> G[maxn];
#define PB push_back
int deg[maxn]; void find_ecc(int n)
{
dfs_clock = ;
tarjan(,-);
ecc_cnt = ;
for(int i = ; i < n; i++){
if(!eccno[i]){
ecc_cnt++;
pid[ecc_cnt] = i;
dfs(i);
}
} for(int i = ; i <= ecc_cnt; i++) G[i].clear();
memset(deg,,sizeof(deg));
for(int i = ; i < ecnt; i+=){
if(cut[i]){
int u = eccno[to[i]], v = eccno[to[i^]];
G[u].PB(v); G[v].PB(u);
deg[u]++; deg[v]++;
}
}
} void init()
{
memset(head,-,sizeof(head));
ecnt = ;
} int MaxD,poi; void dfs(int u,int fa,int d)
{
if(d > MaxD){
MaxD = d;
poi = u;
}
for(int i = ; i <(int)G[u].size(); i++){
int v = G[u][i]; if(v == fa) continue;
dfs(v,u,d+);
}
} void solve()
{
MaxD = ; poi = ;
dfs(,-,);
int u = poi;
MaxD = ; poi = u;
dfs(u,-,);
int v = poi;
printf("%d %d\n",pid[u]+,pid[v]+);
} int main()
{
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
int n,m;scanf("%d%d",&n,&m);
init();
for(int i = ; i < m; i++){
int u,v; scanf("%d%d",&u,&v); u--;v--;
addEdge(u,v); addEdge(v,u);
}
find_ecc(n);
solve();
return ;
}

最新文章

  1. FineReport如何部署Tomcat服务器集群
  2. redis集群安装
  3. 网络资源管理系统LANsurveyor实战体验
  4. Ubuntu10.10 安装scim
  5. SoapUI模拟REST MockService
  6. 推荐自学JAVA开发的三本书
  7. FB面经 Prepare: LCA of Deepest Nodes in Binary Tree
  8. spring-data-mongodb与mongo shell的对应关系
  9. python答题辅助
  10. redis 作为 mysql的缓存
  11. HTTP 错误 500.19 - Internal Server Error 无法读取配置节 system.serviceModel 因为它缺少节声明
  12. AI 概率论
  13. 在android 上 使用 rxjava 入门篇
  14. redis点
  15. (转)OOP(面向对象编程)的几大原则
  16. ubuntu:在ubuntu上安装vmware12
  17. Python之scrapy框架之post传输数据错误:TypeError: to_bytes must receive a unicode, str or bytes object, got int
  18. POJ 3087 Shuffle&amp;#39;m Up(模拟)
  19. 成都Uber优步司机奖励政策(4月4日)
  20. 【转】Pyhton 单行、多行注释符号使用方法及规范

热门文章

  1. 通用后台管理系统UI模板-AdminLTE简介及构造动态菜单栏
  2. .Net HttpWebRequest 爬虫核心爬取
  3. Navicat导出数据库结构为PDF
  4. redis win系统安装并设置开机自启
  5. [Xcode 实际操作]七、文件与数据-(14)数据持久化存储框架CoreData的使用:删除CoreData中的数据
  6. Spring Boot Dubbo 构建分布式服务
  7. 支持通配符查询的k-gram索引
  8. Kaggle 数据挖掘比赛经验分享
  9. CentOS 7 部署 nginx-1.14.2
  10. PostgreSQL - raise函数打印字符串