bzoj2558
哈希+拓扑排序
题意比较绕,先开始没看懂就看了发程序,发现好像理解的不太一样,后来找到了一个题目解释。。。
摘自jcvb:其实就是说颜色相同且三个出口分别对应相同(注意有可能是合并后才相同)两个结点是相同的,可以合并,求最后合并完后剩下几个结点。
所以我们倒着计算一个房间是否和以前相同,因为有可能合并(这是看了题意才知道)导致两个房间变成一个,然后可一个到这个房间的房间的邻接表发生变化,导致其他房间可能相邻,又因为原先图就是拓扑的,前面不会影响后面,所以可以倒着合并。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; const int N = 6010, seed = 19992147; int n, ans; char key[N], t[N]; int id[N], Map[N][4]; map<int, int> mp; int main() { scanf("%d", &n); ans = n; for(int i = 1; i < n; ++i) { scanf("%s", t); key[i] = t[0]; id[i] = i; for(int j = 0; j < 3; ++j) scanf("%d", &Map[i][j]); } for(int i = n - 1; i; --i) { int h = key[i]; for(int j = 0; j < 3; ++j) h = h * seed + id[Map[i][j]]; if(mp.find(h) != mp.end()) id[i] = mp[h], --ans; else mp[h] = id[i]; } printf("%d\n", ans); return 0; }