http://codeforces.com/gym/100676/attachments

题目大意:

有n个城市,有m条路,每条路都有边长,如果某几个城市的路能组成一个环,那么在环中的这些城市就有传送门,能够瞬间抵达对方的城市(即距离为0),否则,就要走这条路,并且经过的路程为这条路的长度。

问,找一个城市作为这些城市的首都

要求:除了首都城市外,其他城市到首都的最大距离最短。

思路:

边双连通缩点以后就是一棵树,找树上的直径,首都一定是直径上的点。(orz,自己明明注意到了一定是直径上面的点,在之前的好多次的wa中却忘了是要找直径上的点了)

//看看会不会爆int!数组会不会少了一维!
//取物问题一定要小心先手胜利的条件
#include <bits/stdc++.h>
using namespace std;
#pragma comment(linker,"/STACK:102400000,102400000")
#define LL long long
#define ALL(a) a.begin(), a.end()
#define pb push_back
#define mk make_pair
#define fi first
#define se second
#define haha printf("haha\n")
/*
思路:
双连通缩点,然后随便找一个点树dp,
树dp,距离最短的肯定就是直径上的某一个点
*/
const int maxn = 1e5 + ;
const int maxm = 2e5 + ;
const LL inf = 1e17;
vector<pair<int, LL> > G[maxn];
int n, m;
/*****************/
int dfstime, bcccnt;
bool iscut[maxn];
int bccnu[maxn], pre[maxn];
stack<int> s;
vector<int> bcc[maxn]; int dfs(int u, int fa){
int lowu = pre[u] = ++dfstime;
int len = G[u].size();
int child = ;
s.push(u);
for (int i = ; i < len; i++){
int v = G[u][i].fi;
if (pre[v] == -){
child++;
int lowv = dfs(v, u);
lowu = min(lowv, lowu);
if (lowv > pre[u]){
iscut[u] = true;
}
}
else if (pre[v] < pre[u] && v != fa){
lowu = min(lowu, pre[v]);
}
}
if (lowu == pre[u]){
bcccnt++;
while (true){///边双连通分量是不存在重点的
int v = s.top(); s.pop();
bccnu[v] = bcccnt;
bcc[bcccnt].pb(v);
if (v == u) break;
}
}
if (fa == - && child == ) iscut[u] = false;
return lowu;
} void get_connect(){
dfstime = bcccnt = ;
memset(iscut, false, sizeof(iscut));
memset(bccnu, , sizeof(bccnu));
memset(pre, -, sizeof(pre));
dfs(, -);
} vector<pair<int, LL> > new_edge[maxn];
void rebuild(){
///O(n + m)
for (int i = ; i <= bcccnt; i++){
for (int j = ; j < bcc[i].size(); j++){
int u = bcc[i][j];
for (int k = ; k < G[u].size(); k++){
int v = G[u][k].fi;
LL val = G[u][k].se;
if (bccnu[u] != bccnu[v]){
new_edge[bccnu[u]].push_back(mk(bccnu[v], val));
}
}
}
}
/* printf("bcccnt = %d\n", bcccnt); cout << "new_edge.output" << endl;
for (int i = 1; i <= bcccnt; i++){
for (int j = 0; j < new_edge[i].size(); j++){
printf("u = %d v = %d val = %d\n", i, new_edge[i][j].fi, new_edge[i][j].se);
}
cout << endl;
}
*/
} int p; LL maxval;
LL can[maxn];
void dfs1(int u, int fa, LL sum){
if (sum > maxval){
maxval = sum, p = u;
}
for (int i = ; i < new_edge[u].size(); i++){
int v = new_edge[u][i].fi;
LL tmp = new_edge[u][i].se;
if (v == fa) continue;
dfs1(v, u, sum + tmp);
}
} LL d1[maxn], d2[maxn];
///d1从最底下到目前节点的距离
///d2表示从根到目前节点的距离
void dfs2(int u, int fa, LL sum){
d2[u] = sum;
for (int i = ; i < new_edge[u].size(); i++){
int v = new_edge[u][i].fi;
LL val = new_edge[u][i].se;
if (v == fa) continue;
dfs2(v, u, sum + val);
d1[u] = max(d1[u], d1[v] + val);
}
} LL mini;
vector<int> ansp;
void dfs3(int u, int fa){
for (int i = ; i < new_edge[u].size(); i++){
int v = new_edge[u][i].fi;
LL val = new_edge[u][i].se;
if (v == fa) continue;
if (d1[u] - val == d1[v]){
dfs3(v, u);
LL tmp = max(d1[u], d2[u]);
if (mini > tmp){
ansp.clear(); mini = tmp; ansp.pb(u);
}
else if (mini == tmp){
ansp.pb(u);
}
}
}
} int main(){
int t; cin >> t;
while (t--){
scanf("%d%d", &n, &m);
for (int i = ; i <= n; i++){
G[i].clear(); bcc[i].clear();
new_edge[i].clear();
}
for (int i = ; i <= m; i++){
int u, v; LL val; scanf("%d%d%lld", &u, &v, &val);
G[u].pb(mk(v, val)); G[v].pb(mk(u, val));
}
get_connect();
rebuild();
p = , maxval = ;
dfs1(, -, ); memset(d1, , sizeof(d1));
memset(d2, , sizeof(d2));
ansp.clear();
dfs2(p, -, 0LL); mini = inf;
dfs3(p, -); int ans = n + ;
for (int i = ; i < ansp.size(); i++){
int u = ansp[i];
for (int j = ; j < bcc[u].size(); j++){
ans = min(ans, bcc[u][j]);
}
}
if (ans == n + ) {ans = , mini = ;}
printf("%d %lld\n", ans, mini);
}
return ;
}

边双连通缩点+树dp 2015 ACM Arabella Collegiate Programming Contest的Gym - 100676H的更多相关文章

  1. Codeforces Gym 2015 ACM Arabella Collegiate Programming Contest(二月十日训练赛)

    A(By talker): 题意分析:以a(int) op b(int)形式给出两个整数和操作符, 求两个整数是否存在操作符所给定的关系 ,有则输出true,无则输出false: 思路:由于无时间复杂 ...

  2. 2015 ACM Arabella Collegiate Programming Contest

    题目链接:https://vjudge.net/contest/154238#overview. ABCDE都是水题. F题,一开始分类讨论,结果似乎写挫了,WA了一发.果断换并查集上,A了. G题, ...

  3. gym100676 [小熊骑士限定]2015 ACM Arabella Collegiate Programming Contest

    Kuma Rider久违的第二场训练,这场很水,又在vj的榜单上看到第一场的大哥了,2小时ak,大哥牛啤! A.水 #include<cstdio> #include<iostrea ...

  4. 18春季训练01-3/11 2015 ACM Amman Collegiate Programming Contest

    Solved A Gym 100712A Who Is The Winner Solved B Gym 100712B Rock-Paper-Scissors Solved C Gym 100712C ...

  5. ACM Arabella Collegiate Programming Contest 2015 H. Capital City 边连通分量

    题目链接:http://codeforces.com/gym/100676/attachments 题意: 有 n 个点,m 条边,图中,边强连通分量之间可以直达,即距离为 0 ,找一个点当做首都,其 ...

  6. 2015 ACM Amman Collegiate Programming Contest 题解

    [题目链接] A - Who Is The Winner 模拟. #include <bits/stdc++.h> using namespace std; int T; int n; s ...

  7. 2015 ACM Syrian Collegiate Programming Contest

    A. My Friend of Misery 计算出答案的上下界即可. 时间复杂度$O(n)$. #include<bits/stdc++.h> using namespace std; ...

  8. ACM Arabella Collegiate Programming Contest 2015 F. Palindrome 并查集

    题目链接:http://codeforces.com/gym/100676/attachments 题意: 给一个字符串,有一些约束条件,两个位置要相同,有一些是问号,求最后有多少种方案回文? 分析: ...

  9. ACM International Collegiate Programming Contest, Tishreen Collegiate Programming Contest (2017)- K. Poor Ramzi -dp+记忆化搜索

    ACM International Collegiate Programming Contest, Tishreen Collegiate Programming Contest (2017)- K. ...

随机推荐

  1. OOP 学习笔记汇总

    1.1 引用 1.2 const关键字 1.3 动态内存分配 1.4 内联函数和重载函数函数参数缺省值 1.5 类和对象的基本概念与用法1 2.1 类和对象的基本概念2

  2. net项目调试时,读取主干或其他项目代码问题

    最近调试项目的时候出了一个很奇怪的问题. 项目总是去读取另外一个项目的配置文件,甚至执行的代码都是另外一个项目的. 我用vs修改代码时候,甚至修改到了其他项目的代码,生成不报错,很奇怪. 本来怀疑是v ...

  3. Markdown github 风格语法

    某些效果cnblog无法支持,见 https://github.com/tanghammer/note/blob/master/Markdown%20github%E9%A3%8E%E6%A0%BC% ...

  4. 敏捷冲刺DAY4

    一. 每日会议 1. 照片 2. 昨日完成工作 登录界面的进一步完善 服务器搭建 建立数据库 3. 今日完成工作 发布和提供需求功能的实现 用户修改自己的信息 用户界面设计 管理员界面设计 4. 工作 ...

  5. sysbench 环境安装,压测mysql

    源码路径:https://github.com/akopytov/sysbench 版本linux 6.8sysbench 0.5mysql 5.6.29 1.安装pip略 2.pip 安装bzr p ...

  6. [BinaryTree] 二叉树常考知识点

    1.二叉树第i层至多有2^(i-1)个结点(i>=1). 2.深度为k的二叉树上,至多含2^k-1个结点(k>=1) 3.n0 = n2 + 1(度) 4.满二叉树:深度为k且含有2^k- ...

  7. wpf下使用NotifyIcon

    以前在winForm下使用过NotifyIcon,到wpf找不到了,在wpf下还是直接用WinForm里的那个NotifyIcon实现最小到系统托盘 定义一个NotifyIcon成员 : Notify ...

  8. MySQL复制 -- 应用场景

    本文行文路径如下: 什么是复制?复制是怎么工作的?复制有哪几种表现形式?复制能解决那些问题?业界有哪些数据同步解决方案? 什么是复制? 官方解释道:Replication enables data f ...

  9. android面试(3)---基本问题

    1.值类型,引用类型? 基本数据类型都是值类型:byte,short,int,long,float,double,char,boolean 其他类型都是引用类型. 引用类型在传入方法是,方法内部对引用 ...

  10. SCWS中文分词,词典词性标注详解

    SCWS中文分词词典条目多达26万条之巨,在整理的时候已经把很多明显不对的标注或词条清理了 ---- 附北大词性标注版本 ----Ag 形语素 形容词性语素.形容词代码为a,语素代码g前面置以A. a ...