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个树状数组
随机推荐
- windows和linux安装rabbitmq
一.windows安装rabbitmq 1.安装erlang 点击进入官网下载:http://erlang.org/download/ 2.安装rabbitmq 点击进入官网下载:http://www ...
- Spark Streaming整合logstash + Kafka wordCount
1.安装logstash,直接解压即可 测试logstash是否可以正常运行 bin/logstash -e 'input { stdin { } } output { stdout {codec = ...
- python--线程锁,队列
#线程数据安全处理--同步锁 import time def sub(): global num print("ok") lock.acquire()#获取这把锁--->只有 ...
- VB中的SSTab控件隐藏选项卡方法
请教下,VB中Sstab控件,如何隐藏选项卡呢? SSTab1.TabVisible(1) = False object.TabVisible(tab) [ = boolean ] tab 数值表达式 ...
- 01JAVA入门
1 Welcome to java public class ch01Welcome { public static void main(String[] args) { System.out.pri ...
- AtCoder Regular Contest 092 2D Plane 2N Points AtCoder - 3942 (匈牙利算法)
Problem Statement On a two-dimensional plane, there are N red points and N blue points. The coordina ...
- vector存放结构体数据的2种方法
如果要在Vector容器中存放结构体类型的变量,经常见到两种存放方式. 方式一:放入这个结构体类型变量的副本. 方式二:放入指向这个结构体类型变量的指针. 假设结构体类型变量是这样的, typedef ...
- Spring缓存机制(转)
Spring的缓存机制非常灵活,可以对容器中任意Bean或者Bean的方法进行缓存,因此这种缓存机制可以在JavaEE应用的任何层次上进行缓存. Spring缓存底层也是需要借助其他缓存工具来实现,例 ...
- jenkins上job误删除怎么恢复
1.点击jobConfigHistory 2.点击Show deleted jobs only 3.找到被删除的 记录,点击Restore
- 【LeetCode】排序 sort(共20题)
链接:https://leetcode.com/tag/sort/ [56]Merge Intervals (2019年1月26日,谷歌tag复习) 合并区间 Input: [[1,3],[2,6], ...