题目链接 HDU 6251

题意 给出一个$N$个点$N$条边的无向图。然后给出$M$个操作,每个操作为$(x, y, z)$,表示把连接

$x$和$y$的边的颜色改成$z$。

求这张无向图中所有边的颜色的连通块数量。

首先不难得到这是一个环套树的结构。

首先考虑一棵树的情形。

设$f[i]$为$i$这个结点的所有边中的不同颜色数目。

那么整棵树的所有边的颜色的连通块数量即为$∑f(i) - (n - 1)$

现在把这个结论推广到环套树上。

设$f[i]$为$i$这个结点的所有边中的不同颜色数目。

那么整个图的所有边的颜色的连通块数量即为$∑f(i) - n$

但是有一种特殊情况,若这个环上所有的边的颜色相同,

那么整个图的所有边的颜色的连通块数量为$∑f(i) - (n - 1)$

#include <bits/stdc++.h>

using namespace std;

#define	rep(i, a, b)	for (int i(a); i <= (b); ++i)
#define dec(i, a, b) for (int i(a); i >= (b); --i)
#define MP make_pair
#define fi first
#define se second typedef pair <int, int> PII; const int N = 2e5 + 10; unordered_map <int, int> mp[N], cp;
map <PII, int> mp2;
map <PII, int> oncircle; vector <int> v[N];
int T;
int n, m, cnt;
int isroot[N];
int a[N], vis[N];
int father[N];
int f[N];
int ans;
int cir;
int ca = 0; int getcircle(int x){
vis[x] = 1;
for (auto u : v[x]){
if (u == father[x]) continue;
father[u] = x;
if (vis[u]){
cnt = 0;
int w = x;
while (w ^ u){
a[++cnt] = w;
isroot[w] = cnt;
w = father[w];
} a[++cnt] = u;
isroot[u] = cnt;
return 1;
} if (getcircle(u)) return 1;
} return 0;
} int main(){ scanf("%d", &T);
while (T--){
printf("Case #%d:\n", ++ca);
scanf("%d%d", &n, &m);
rep(i, 0, n + 1) v[i].clear();
rep(i, 0, n + 1) mp[i].clear();
mp2.clear();
oncircle.clear();
cp.clear();
cnt = 0;
rep(i, 0, n + 1) a[i] = 0;
rep(i, 0, n + 1) f[i] = 0;
ans = 0;
cir = 0;
rep(i, 1, n){
int x, y, z;
scanf("%d%d%d", &x, &y, &z);
if (x > y) swap(x, y);
v[x].push_back(y);
v[y].push_back(x);
if (mp[x][z] == 0){
++f[x];
++mp[x][z];
} else ++mp[x][z];
if (mp[y][z] == 0){
++f[y];
++mp[y][z];
} else ++mp[y][z];
mp2[MP(x, y)] = z;
} rep(i, 1, n) ans += f[i]; rep(i, 0, n + 1) vis[i] = 0;
getcircle(1); a[++cnt] = a[1];
rep(i, 1, cnt - 1){
int x = a[i], y = a[i + 1];
if (x > y) swap(x, y);
oncircle[MP(x, y)] = 1;
} for (auto u : oncircle){
int tt = mp2[MP(u.fi.fi, u.fi.se)];
if (cp[tt] == 0){
++cir;
++cp[tt];
} else ++cp[tt];
} while (m--){
int x, y, z;
scanf("%d%d%d", &x, &y, &z);
if (x > y) swap(x, y);
int old = mp2[MP(x, y)];
--mp[x][old];
if (mp[x][old] == 0) --f[x], --ans;
--mp[y][old];
if (mp[y][old] == 0) --f[y], --ans; if (oncircle.count(MP(x, y)) > 0){
--cp[old];
if (cp[old] == 0) --cir;
} mp2[MP(x, y)] = z;
if (mp[x][z] == 0){
++mp[x][z];
++f[x];
++ans;
} else ++mp[x][z]; if (mp[y][z] == 0){
++mp[y][z];
++f[y];
++ans;
} else ++mp[y][z]; if (oncircle.count(MP(x, y)) > 0){
if (cp[z] == 0){
++cp[z];
++cir;
} else ++cp[z];
} if (cir == 1) printf("%d\n", ans - n + 1);
else printf("%d\n", ans - n);
}
} return 0;
}

HDU 6251 Inkopolis(2017 CCPC-Final,I题,环套树 + 结论)的更多相关文章

  1. HDU 6268 Master of Subgraph (2017 CCPC 杭州 E题,树分治 + 树上背包)

    题目链接  2017 CCPC Hangzhou  Problem E 题意  给定一棵树,每个点有一个权值,现在我们可以选一些连通的点,并且把这点选出来的点的权值相加,得到一个和. 求$[1, m] ...

  2. HDU 6271 Master of Connected Component(2017 CCPC 杭州 H题,树分块 + 并查集的撤销)

    题目链接  2017 CCPC Hangzhou Problem H 思路:对树进行分块.把第一棵树分成$\sqrt{n}$块,第二棵树也分成$\sqrt{n}$块.    分块的时候满足每个块是一个 ...

  3. 2017 ccpc哈尔滨 A题 Palindrome

    2017 ccpc哈尔滨 A题 Palindrome 题意: 给一个串\(T\),计算存在多少子串S满足\(S[i]=S[2n−i]=S[2n+i−2](1≤i≤n)\) 思路: 很明显这里的回文串长 ...

  4. 2017 CCPC秦皇岛 A题 A Ballon Robot

    The 2017 China Collegiate Programming Contest Qinhuangdao Site is coming! There will be  teams parti ...

  5. 2017 CCPC秦皇岛 E题 String of CCPC

    BaoBao has just found a string  of length  consisting of 'C' and 'P' in his pocket. As a big fan of ...

  6. 2017 CCPC秦皇岛 M题 Safest Buildings

    PUBG is a multiplayer online battle royale video game. In the game, up to one hundred players parach ...

  7. 2017 CCPC秦皇岛 L题 One Dimensions Dave

    BaoBao is trapped in a one-dimensional maze consisting of  grids arranged in a row! The grids are nu ...

  8. 2017 CCPC秦皇岛 H题 Prime set

    Given an array of  integers , we say a set  is a prime set of the given array, if  and  is prime. Ba ...

  9. 2017 CCPC秦皇岛 G题 Numbers

    DreamGrid has a nonnegative integer . He would like to divide  into nonnegative integers  and minimi ...

随机推荐

  1. 常州大学新生寒假训练会试 I 合成反应

    题目描述 有机合成是指从较简单的化合物或单质经化学反应合成有机物的过程. 有时也包括从复杂原料降解为较简单化合物的过程. 由于有机化合物的各种特点,尤其是碳与碳之间以共价键相连,有机合成比较困难,常常 ...

  2. Xadmin添加用户小组件出错render() got an unexpected keyword argument 'renderer

    环境: Python 3.5.6 Django 2.1 Xadmin 原因: render函数在django2.1上有变化 解决方案: 1.在Python终端输入命令help('xadmin') 查看 ...

  3. Python中bisect的使用方法

    Python中列表(list)的实现其实是一个数组,当要查找某一个元素的时候时间复杂度是O(n),使用list.index()方法,但是随着数据量的上升,list.index()的性能也逐步下降,所以 ...

  4. js 监听后退事件及跳转页面

    //直接跳转 window.location.href="b.html"; //返回上一级页面 window.history.back(-1); //返回下一级页面 window. ...

  5. Java Integer于Int 进行==双等于的内存比较时的一些问题说明

    转自: https://blog.csdn.net/xingkongdeasi/article/details/79618421 部分有所修改: 前言: 越是简单的东西,我们往往越是没有去把它明白,但 ...

  6. windows下,cmd 运行 python 脚本,选中文字就停止运行了【已解决】

    参考资料: https://jingyan.baidu.com/article/ce09321bb95dda2bff858f26.html 问题原因: cmd 里面,快速编辑模式会暂停程序 解决步骤: ...

  7. spring整合mybatis详解

    在上篇螃蟹已经说明spring注解的最经典配置,接下来开始整合mybatis,这样整个项目就相对完整了. 有关本实例的源码可以到 <spring MVC注解实例及说明文档> 下载. 如需转 ...

  8. [网站公告]11月26日00:00-04:00阿里云RDS升级

    大家好,11月26号00:00-04:00(今天夜里),阿里云将对我们所用的SQL Server RDS实例所在的物理主机做升级操作(目前博客园整站运行于阿里云上),升级期间RDS实例会有2次闪断,每 ...

  9. Mybatis使用- Mybatis JdbcType与Oracle、MySql数据类型对应列表 ; Mybatis中javaType和jdbcType对应关系

    Mybatis JdbcType与Oracle.MySql数据类型对应列表  Mybatis JdbcType Oracle MySql JdbcType ARRAY     JdbcType BIG ...

  10. IO Streams:来源于命令行的IO

    简介 程序经常从命令行运行并与在命令行环境中的用户交互.Java平台支持这种互动的方式有两种:通过标准流,通过控制台 标准流 标准流是许多操作系统的一项功能.默认情况下,他们从键盘输入读取和输出到显示 ...