HDU 6251 Inkopolis(2017 CCPC-Final,I题,环套树 + 结论)
题目链接 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题,环套树 + 结论)的更多相关文章
- HDU 6268 Master of Subgraph (2017 CCPC 杭州 E题,树分治 + 树上背包)
题目链接 2017 CCPC Hangzhou Problem E 题意 给定一棵树,每个点有一个权值,现在我们可以选一些连通的点,并且把这点选出来的点的权值相加,得到一个和. 求$[1, m] ...
- HDU 6271 Master of Connected Component(2017 CCPC 杭州 H题,树分块 + 并查集的撤销)
题目链接 2017 CCPC Hangzhou Problem H 思路:对树进行分块.把第一棵树分成$\sqrt{n}$块,第二棵树也分成$\sqrt{n}$块. 分块的时候满足每个块是一个 ...
- 2017 ccpc哈尔滨 A题 Palindrome
2017 ccpc哈尔滨 A题 Palindrome 题意: 给一个串\(T\),计算存在多少子串S满足\(S[i]=S[2n−i]=S[2n+i−2](1≤i≤n)\) 思路: 很明显这里的回文串长 ...
- 2017 CCPC秦皇岛 A题 A Ballon Robot
The 2017 China Collegiate Programming Contest Qinhuangdao Site is coming! There will be teams parti ...
- 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 ...
- 2017 CCPC秦皇岛 M题 Safest Buildings
PUBG is a multiplayer online battle royale video game. In the game, up to one hundred players parach ...
- 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 ...
- 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 ...
- 2017 CCPC秦皇岛 G题 Numbers
DreamGrid has a nonnegative integer . He would like to divide into nonnegative integers and minimi ...
随机推荐
- HTML插入文件链接(如音乐,照片)
html中插入音频.H5的标签 src为本地 <audio controls="> <source src="韩庚 - I Don't Give A 屑.mp3& ...
- 14,UA池和代理池
今日概要 scrapy下载中间件 UA池 代理池 一,下载中间件(Downloader Middlewares) 位于scrapy引擎和下载器之间的一层组件. - 作用: (1)引擎将请求传递给下载器 ...
- Redis实现之AOF持久化
AOF持久化 除了RDB持久化功能之外,Redis还提供了AOF(Append Only File)持久化功能,与RDB持久化通过保存数据库中的键值对来记录数据库状态不同,AOF持久化是通过保存Red ...
- data相关应用
文案参考:HTML5中的data-*属性和jQuery中的.data()方法使用 data属性选择器 $("li[data-id='1']")//选择li元素中data-id属性等 ...
- Android学习笔记之-----讯飞语音识别实例化RecognizerDialog参数出现错误的解决方法
本人也是个小菜鸟,在做语音识别时也遇到了这个问题,空指针一直报错,app程序停止运行. 在网上搜了半天在这个帖子里找到了解决方法:http://bbs.xfyun.cn/forum.php?mo .. ...
- WebApp开发技巧
http://www.cnblogs.com/WhiteCusp/p/4502961.html http://ju.outofmemory.cn/entry/25675 http://www.fron ...
- Win 10激活
Win10专业版激活(亲测有效) 来源:http://jingyan.baidu.com/article/295430f1ce2e880c7e0050ff.html 1.首先,我们先查看一下Win10 ...
- 【Linked List Cycle II】cpp
题目: Given a linked list, return the node where the cycle begins. If there is no cycle, return null. ...
- 04 JVM是如何执行方法调用的(上)
重载和重写 重载:同一个类中定义名字相同的方法,但是参数类型或者参数个数必须不同. 重载的方法在编译过程中就可完成识别.具体到每一个方法的调用,Java 编译器会根据所传入参数的生命类型来选取重载方法 ...
- 数据结构算法——链表的各种操作,C++和Python
时隔已久,一直没更新博客,感觉很愧疚呀. 先贴上所有的代码.这个是用C++写的 #include "stdafx.h" //Author:Albert //Date: 2018.1 ...