DAY 6 TEST
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个树状数组
随机推荐
- P1079Vigenère密码
这是2012年noip提高组的的DAY1T1,我用了一下午的时间,一次性AC^^. 这是一个字符串的模拟题.首先给出了一个密码对应法则,我们发现在同一对角线的明文通过密钥得出来的密文是相同的.根据八皇 ...
- 攻防世界--when_did_you_born5
测试文件:https://adworld.xctf.org.cn/media/task/attachments/24937e95ca4744818feebe82ab96902d 1.准备 root@l ...
- MFC- 网络编程
一.MFC网络编程 a)CAsyncSocket用于异步非阻塞类,用UDP通信: b)CAsyncSocket的子类(派生类):Csocket同步阻塞类,用于TCP通信: c)通信前,必须调用AfxS ...
- Django rest_frameword 之项目流程
后端开发软件目录规范 一.Model from django.db import models # Create your models here. # 多表的设计 # 图书 作者 出版社 作者详情表 ...
- js中的函数防抖与节流
一.滚动条监听的例子 写一个功能需求-- 监听浏览器滚动事件,返回当前滚条与顶部的距离,代码如下: function showTop () { var scrollTop = document.bod ...
- LOAD - 装载或重载一个共享库文件
SYNOPSIS LOAD 'filename' DESCRIPTION 描述 这个命令装载一个共享库文件到PostgreSQL服务器的地址空间. 一旦一个文件被装载,如果该文件前面曾经装载过,那么服 ...
- tf Dataset API
https://zhuanlan.zhihu.com/p/30751039 https://zhuanlan.zhihu.com/p/37106443 关于其中shuffle时的buffer_size ...
- activity manager
首先 activity manager 作为一个独立的服务存在,所有系统中的所有 app 的 activity 都通过这个 service 来管理 同时 activity manager 维护着多个 ...
- 给定两个大小为 m 和 n 的有序数组 nums1 和 nums2。 请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))。 你可以假设 nums1 和 nums2 不会同时为空。
class Solution { public double findMedianSortedArrays(int[] A, int[] B) { int m = A.length; int n = ...
- php 强制类型转换
123 123.01 array("123",123) true false null (string) "123" "123.01" ...