HDU 4467 Graph
2015-09-02 18:37
330 查看
传送门
我们把度大于等于n−−√的点称为重点,其他的点称为轻点。
对于每一个重点u,维护另一端颜色是c的他的边的和sum[u][c]。
我们对于轻点和重点之间的边,只考虑轻点向重点的边。
也就是我们更改重点u时,和他相连的轻点不用考虑,更改和他相连的重点的sum[v][c]。
维护ans[x+y]为两端颜色分别是x和y的边和。
我们把度大于等于n−−√的点称为重点,其他的点称为轻点。
对于每一个重点u,维护另一端颜色是c的他的边的和sum[u][c]。
我们对于轻点和重点之间的边,只考虑轻点向重点的边。
也就是我们更改重点u时,和他相连的轻点不用考虑,更改和他相连的重点的sum[v][c]。
维护ans[x+y]为两端颜色分别是x和y的边和。
#include <bits/stdc++.h> using namespace std; typedef long long ll; #define prt(k) cout<<#k" = "<<k<<endl const int N = 100100; bool key ; int du ; int n, m, Q; int color ; map<pair<int,int>, ll> mp; #define MP make_pair struct edge { int v; ll w; edge() {} edge(int a, ll b) { v = a; w = b; } } ; vector<edge> g ; int head , mm; ll sum [2]; ll ans[5]; void add(int u, int v, ll w) { g[u].push_back(edge(v, w)); } void initsum() { mm = 0; memset(head, -1, sizeof head); for (int i=0;i<N;i++) g[i].clear(); mp.clear(); memset(du, 0, sizeof du); memset(key, false, sizeof key); memset(sum, 0, sizeof sum); memset(ans, 0, sizeof ans); } void update(int u) { if (key[u]) { for (auto p : g[u]) { sum[p.v][color[u]] -= p.w; sum[p.v][color[u]^1] += p.w; } } else { sum[u][0] = sum[u][1] = 0; for (auto p : g[u]) { sum[u][color[p.v]] += p.w; if (key[p.v]) { sum[p.v][color[u]] -= p.w; sum[p.v][color[u]^1] += p.w; } } } ans[color[u]] -= sum[u][0]; ans[color[u] + 1] -= sum[u][1]; ans[color[u]^1] += sum[u][0]; ans[(color[u]^1) + 1] += sum[u][1]; color[u] ^= 1; } int main() { int ca = 1; while (scanf("%d%d", &n, &m)==2) { initsum(); for (int i=1;i<=n;i++) scanf("%d", color+i); for (int i=0;i<m;i++) { int u, v; ll w; scanf("%d%d%I64d", &u, &v, &w); if (u > v) swap(u, v); mp[MP(u, v)] += w; } int lim = sqrt(n+0.5); for (auto p : mp) { int u, v; ll w; u=p.first.first; v=p.first.second; if (++du[u]>=lim) key[u] = true; if (++du[v]>=lim) key[v] = true; } for (auto p : mp) { int u, v; ll w; u=p.first.first; v=p.first.second; w = p.second; if (key[u] && key[v]) { add(u, v, w); add(v, u, w); } if (!key[u]) add(u, v, w); if (!key[v]) add(v, u, w); ans[color[u] + color[v]] += w; sum[u][color[v]] += w; sum[v][color[u]] += w; } scanf("%d", &Q); printf("Case %d:\n", ca++); while (Q--) { char op[20]; scanf("%s", op); if (op[0]=='A') { int x, y; scanf("%d%d", &x, &y); printf("%I64d\n", ans[x + y]); } else { int u; scanf("%d", &u); update(u); } } } return 0; }
相关文章推荐
- 分析HTTP请求返回304状态码
- 771 密钥解密【字符串处理】
- 游标
- 深入解析HTML5使用SVG图像时的viewBox属性用法
- iscsi挂载远端磁盘的学习笔记
- Android之发送接收服务器消息
- 多进程模型和Slect模型服务器介绍
- mysql插入数据产生中文乱码问题
- strcmp函数实现源码
- HTTP Status 500 No adapter for handler
- 大自然的精神
- mysql触发器
- linux下shell显示-bash-4.1#不显示路径解决方法
- 解析xml
- html meta link script form
- hihocoder-1196 : 高斯消元·二
- JSTL与EL表达式(为空判断)
- Linux下Makefile快速编写入门
- 关于overload和override
- el表达式简介