BZOJ4999 JZOJ5112【usaco2017_Mar Platinum】Switch Grass
来源:互联网 发布:淘宝的林国庆 编辑:程序博客网 时间:2024/05/20 07:32
Description
Farmer John has recently been experimenting with cultivating different types of grass on his farm, realizing that different types of cows like different types of grass. However, he must be careful to ensure that different types of grass are planted sufficiently far away from each-other, in order to prevent them from being inextricably mixed.
FJ’s farm consists of
In each field, FJ initially plants one of
After each update, FJ would like to know the length of the shortest path between two fields having different grass types. That is, among all pairs of fields having different grass types, he wants to know which two are closest. Ideally, this number is large, so he can prevent grass of one type from mixing with grass of another type. It is guaranteed that the farm will always have at least two fields with different grass types.
In 30 percent of the input cases, each field will be directly connected to at most 10 pathways.
Input
The first line of input contains four integers,
Output
For each update, print the length of the shortest path between two fields with different types of grass, after the update is applied.
Sample Input
3 2 3 4
1 2 3
2 3 1
1 1 2
3 3
2 3
1 2
2 2
Sample Output
1
3
3
1
吹水:
第一次在JZOJ上做全英文的模拟赛,虽然以前在USACO已经做了几场,但这次感觉还是不一样的,并且一上来就是USACO三月全新的铂金组,挺有挑战。
题目大意:
估计也没有人想去翻译题目。
给出一个联通无向图,没有重边,每条边有一个正权值,每个点有一个颜色,每次修改一个点的颜色,求新图中连接两个颜色不同的点的路径的最短距离。
题解:
性质1:最短路径一定就是一条边,我想不用解释了。
性质2:答案一定在原图的最小生成树的某一条边上,这个也很好想,假设x,y颜色不同,有一条连接它们的边、在最小生成树外,那么x,y在最小生成树上的路径上一定有一条边两点颜色不同。
我们需要每个点到它不同颜色子节点的最小值,再把每个点的最小值用数据结构(堆)维护一个最小值。
每个点,每个颜色,开一个堆,表示这个点的这个颜色的子节点的值的情况。
每个点,再开一个堆,一个颜色只会在堆里出现,表示它这个颜色到那个的最小值。
要知道每个点到它不同颜色子节点的最小值,就判断它到所有颜色的子节点的最小值是否和它的颜色相等,相等就去最小。
然后怎么就发现怎么是O(n^3 log n)的呢?
颜色用map,堆用multiset,然后就发现是O(n log n)。
Code:
#include<map>#include<set>#include<cstdio>#include<cstring>#include<algorithm>#define fo(i, x, y) for(int i = x; i <= y; i ++)using namespace std;const int Maxn = 200005, INF = 1e9;typedef pair<int, int> P;typedef multiset<int> T;typedef map<int, T> M;M a[Maxn];multiset<P> b[Maxn];T c;struct node { int x, y, z;}bb[Maxn];int n, m, k, q, x, y, z, color[Maxn], f[Maxn], bz[Maxn], fa[Maxn], fav[Maxn], d[Maxn];int final[Maxn], tot;struct egde { int to, next, v;}e[Maxn * 2];void read(int &x) { char ch = ' '; x = 0; for(;ch < '0' || ch > '9'; ch = getchar()); for(;ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - 48;}bool rank_b(node a, node b) {return a.z < b.z;}int find(int x) {return f[x] == x ? x : (f[x] = find(f[x]));}void link(int x, int y, int z) { e[++ tot].next = final[x], e[tot].to = y, e[tot].v = z, final[x] = tot; e[++ tot].next = final[y], e[tot].to = x, e[tot].v = z, final[y] = tot;}void Init() { scanf("%d %d %d %d", &n, &m, &k, &q); fo(i, 1, m) { read(bb[i].x); read(bb[i].y); read(bb[i].z); } fo(i, 1, n) read(color[i]);}multiset<P> :: iterator it;void Gai_d(int x) { if(d[x] != INF) c.erase(c.find(d[x])); P v = (*b[x].begin()); it = b[x].begin(); int o = b[x].size(); if((v.second == color[x] && o == 1) || !o) d[x] = INF; else { if(v.second == color[x]) d[x] = (*(++ it)).first; else d[x] = (*it).first; c.insert(d[x]); }}void Gai(int x, int y, int z, int bz, int c1, int c2) { int u = *a[x][c1].begin(), v = a[x][c1].size(); if(v) b[x].erase(b[x].find(make_pair(u, c1))); if(bz) a[x][c1].erase(a[x][c1].find(z)); if(!a[x][c1].empty()) b[x].insert(make_pair(, c1)); if(!a[x][c2].empty()) b[x].erase(b[x].find(make_pair(*a[x][c2].begin(), c2))); a[x][c2].insert(z); b[x].insert(make_pair(*a[x][c2].begin(), c2)); Gai_d(x);}void dg_mak(int x) { bz[x] = 1; for(int k = final[x]; k; k = e[k].next) { int y = e[k].to, z = e[k].v; if(bz[y]) continue; Gai(x, y, z, 0, color[y], color[y]); fa[y] = x; fav[y] = z; dg_mak(y); }}void Build() { sort(bb + 1, bb + m + 1, rank_b); fo(i, 1, n) f[i] = i; fo(i, 1, m) { x = bb[i].x, y = bb[i].y, z = bb[i].z; if(find(x) != find(y)) { f[f[x]] = f[y]; link(x, y, z); } } fo(i, 1, n) d[i] = INF; dg_mak(1);}void End() { fo(i, 1, q) { read(x); read(y); if(fa[x]) Gai(fa[x], x, fav[x], 1, color[x], y); color[x] = y; Gai_d(x); printf("%d\n", (*c.begin())); }}int main() { freopen("grass.in", "r", stdin); freopen("grass.out", "w", stdout); Init(); Build(); End();}
- BZOJ4999 JZOJ5112【usaco2017_Mar Platinum】Switch Grass
- jzoj 5113 【usaco2017_Mar Platinum】COWBASIC
- JZOJ 5111. 【usaco2017_Mar Platinum】Modern Art
- Platinum
- grass
- BZOJ 4777 Usaco2017 Open Switch Grass Kruskal+线段树
- bzoj 4777: [Usaco2017 Open]Switch Grass 线段树+最小生成树+set
- BZOJ4999 树剖+动态开点
- Platinum积累
- 【bzoj4999】This Problem Is Too Simple!
- Grass Land
- Best Grass
- uva10382Watering Grass
- Watering Grass
- Best Grass
- android NDK 编译 Platinum
- About The Platinum UPnP
- Platinum UPnP SDK
- 日常训练 Idiot 的集合
- [BFS+康托展开]Hdu 1043 Eight
- GNU C 的一大特色__attribute__ 机制
- 哪个大夫哪天值班
- 有序广播
- BZOJ4999 JZOJ5112【usaco2017_Mar Platinum】Switch Grass
- javaweb文件上传与下载
- 重温《并发编程实战》---任务执行
- 静态资源过滤
- SpringMVC拦截器,json字符串输出,
- sql语句整理
- Angular基础1 在路由时传递参数的方法
- LeetCode 405. Convert a Number to Hexadecimal
- Java生成验证码