test


T1

样例输入


样例输出


答案选择u,v作为关键点

暴力的话k^2枚举跑最短路,寻找最小值就行了

50pts

考虑优化枚举量

因为答案的两个点是不同的点,所以编号的二进制表示中至少一位不同

枚举二进制每一位

假设枚举到第i位,把这一位是1的设为源点,0的设为汇点,跑多源多汇最短路

这两个集合既可以是1~n,也可以是1~k

显然1~k更优一些

建一个超级源点,向所有第一集合的点连长度为0的边

超级汇点同理

跑超级源点到超级汇点的最短路

跑32次得到最优解

#include <queue>
#include <cstdio>
#include <cstring> template <class cls>
inline cls min(const cls & a, const cls & b) {
return a < b ? a : b;
} const int mxn = ;
const int mxm = ;
const int inf = 0x3f3f3f3f; int n, m, k; int points[mxn]; int tot;
int hd[mxn];
int nt[mxm];
int to[mxm];
int vl[mxm]; inline void add_edge(int u, int v, int w) {
nt[++tot] = hd[u];
to[tot] = v;
vl[tot] = w;
hd[u] = tot;
} int dis[mxn]; struct data {
int u, d; data(int _u, int _d) :
u(_u), d(_d) {} bool operator < (const data & that) const {
return d > that.d;
}
}; std::priority_queue<data> heap; int main() {
int cas;
scanf("%d", &cas);
for (int c = ; c < cas; ++c) {
scanf("%d%d%d", &n, &m, &k);
memset(hd, , sizeof(int) * (n + )); tot = ;
for (int i = , u, v, w; i < m; ++i) {
scanf("%d%d%d", &u, &v, &w);
add_edge(u, v, w);
add_edge(v, u, w);
}
for (int i = ; i < k; ++i)
scanf("%d", points + i);
int ans = inf;
for (int i = ; i < k; i <<= ) {
memset(dis, inf, sizeof(int) * (n + ));
for (int j = , p; j < k; ++j)
if (p = points[j], (j & i) == )
heap.push(data(p, dis[p] = ));
while (!heap.empty()) {
int u = heap.top().u;
int d = heap.top().d;
heap.pop();
if (dis[u] != d)
continue;
for (int e = hd[u], v, w; e; e = nt[e])
if (v = to[e], w = vl[e], dis[v] > d + w)
heap.push(data(v, dis[v] = d + w));
}
for (int j = , p; j < k; ++j)
if (p = points[j], (j & i) != )
ans = min(ans, dis[p]);
}
printf("%d\n", ans == inf ? - : ans);
}
return ;
}

T2



建反向边,tarjan然后拓扑就行了

我的思路是tarjan缩点,一个强连通分量的初始ans就是这个强连通分量里面点的最大值。然后建立新图,找到入度为0的点开始dfs,然后更新强连通分量的ans。

询问点就是找点所在的强连通分量,输出强连通分量的ans就ok



先树剖

支持单点修改,查询区间内值为x的数

如何在序列内实现

如果x比较少,完全可以建几棵线段树来实现

每次修改就是在一棵线段树内-1,另一棵+1

多了怎么办?

暴力:开100个树状数组,和刚才没什么区别

如果线段树

在每一个节点上维护一个100的数组

合并的时候可以直接暴力统计节点次数,这样代价是区间长度

如果每一位枚举则是n*100

每一层访问的点是n的,一共log层

onlogn

离线操作

-1和+1分别隶属于x和y棵线段树

把操作分类,每一次处理每一棵的线段树

有多少个颜色就有多少棵

所有操作次数相加就是2m

所以操作还是o(m)

另一种不用树剖的方法

把节点按照DFS序排下来,一个点修改的时候会对他所有子树产生影响

查询的时候 (a-->root)+(b-->root)-(lca(a,b)-->root)+(lca(a,b))

开100个树状数组

随机推荐

  1. 06: django+celery+redis

    目录: 1.1 Celery介绍 1.2 celery 组件 1.3 安装相关包 与 管理命令 1.4 celery与Django执行异步任务 1.5 在django中使用计划任务功能 1.1 Cel ...

  2. C#设计模式:访问者模式(Vistor Pattern)

    一,访问者模式是用来封装一些施加于某种数据结构之上的操作.它使得可以在不改变元素本身的前提下增加作用于这些元素的新操作,访问者模式的目的是把操作从数据结构中分离出来. 二,代码 using Syste ...

  3. Docker:删除images报错(Error response from daemon: conflict: unable to delete 6885a5e3712a (must be forced) - image is being used by stopped container 0cf27d7d29c7)

    1.进入root权限 sudo su 2.停止所有的container,这样才能够删除其中的images: docker stop $(docker ps -a -q) 如果想要删除所有contain ...

  4. ECMAScrip5 二

    一.ES5的严格模式 在严格模式下,声明变量必须使用 var 在严格模式下,不能使用八进制 在严格模式下,不能使用arguments.callee 在严格模式下,不能使用eval()    //eva ...

  5. IDEA显示Run Dashboard窗口

    接下来在workspace.xml RunDashBoard节点中添加如下内容:<component name="RunDashboard"> 在代码中加入 <o ...

  6. CenterOS7中解决No package mysql-server available.

    CenterOS7中解决No package mysql-server available. 1.使用yum install -y mysql-server报错如下: [root@heyong_jd ...

  7. python中的@property

    @property 可以将python定义的函数“当做”属性访问,从而提供更加友好访问方式,但是有时候setter/getter也是需要的 class People: def __init__(sel ...

  8. python并发编程中的多进程(代码实现)

    一.multipricessing模块的介绍 python中的多线程无法利用多核优势,如果想要充分的使用多核CPU资源,在python中大部分情况下需要用多线程,python提供了multiproce ...

  9. Azure IoT 技术研究系列1

    物联网技术已经火了很多年了,业界各大厂商都有各自成熟的解决方案.我们公司主要搞新能源汽车充电,充电桩就是我们物联网技术的最大应用,车联网.物联网. 互联网三网合一.作为Azure重要的Partner和 ...

  10. DevExpress v18.2版本亮点——Office File API 篇

    行业领先的.NET界面控件——DevExpress v18.2版本亮点详解,本文将介绍了DevExpress Office File API v18.2 的版本亮点,新版30天免费试用!点击下载> ...