上海市高校大学生程序设计邀请赛 C:小花梨判连通
Posted albert-biu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了上海市高校大学生程序设计邀请赛 C:小花梨判连通相关的知识,希望对你有一定的参考价值。
Problem C、小花梨判连通
Description
小花梨给出??个点,让??位同学对这??个点任意添加无向边,构成??张图。小花梨想知道对于
每个点??,存在多少个点??(包括??本身),使得??和??在这??张图中都是连通的。
Input
第一行输入两个正整数??和??,分别表示点的个数和同学数。
接下来分成??部分进行输入,每部分输入格式相同。
每部分第一行输入一个整数????,表示第??位同学连边的数目。
接下来????行,每行两个正整数??, ??,表示第??位同学将点??和点??之间进行连接。
可能会存在重边或者自环。
(1 ≤ ?? ≤ 100000,1 ≤ ?? ≤ 10,1 ≤ ??, ?? ≤ ??, 0 ≤ ???? ≤ 200000)
Output
输出??行,第??行输出在??张图中都和编号为??的点连通的点的数目(包括??本身)
Example
Sample Input
4 2
3
1 2
1 3
2 3
2
1 2
3 4
Sample Output
2
2
1
1
对每一个图dfs求联通块并染色,处于同一个联通块中的点染成相同的颜色。染色之后对于图中的每一个点就有一个长度为k的颜色序列,两点在k张图中均联通即两个点的颜色序列完全相同。求每个点的颜色序列的hash值,并记录每种hash值出现了多少次。输出答案时将该点对应的hash值出现的次数输出即可。
#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
const int mod = 1e9 + 7;
const int maxn = 1e5 + 100;
const int inf = 0x3f3f3f3f;
bool vis[maxn];
vector<int> e[11][maxn];
unsigned long long ans[maxn];
int c[11][maxn];
int col = 0;
map<unsigned long long, int> mp;
void dfs(int deep, int now) {
if (vis[now]) return;
c[deep][now] = col;
vis[now] = true;
for (auto p:e[deep][now]) {
dfs(deep, p);
}
}
int main() {
//freopen("in.txt", "r", stdin);
int n, k, m;
scanf("%d %d", &n, &k);
int u, v;
for (int i = 0; i < k; i++) {
cin >> m;
for (int j = 0; j < m; j++) {
scanf("%d %d", &u, &v);
e[i][u].push_back(v);
e[i][v].push_back(u);
}
col = 0;
memset(vis, 0, sizeof(vis));
for (int j = 1; j <= n; j++) {
if (!vis[j]) col++;
dfs(i, j);
}
}
unsigned long long hash;
for (int i = 1; i <= n; i++) {
hash = 0;
for (int j = 0; j < k; j++) {
hash = hash * mod + c[j][i];
}
mp[hash]++;
ans[i] = hash;
}
for (int i = 1; i <= n; i++) {
cout << mp[ans[i]] << endl;
}
return 0;
}
以上是关于上海市高校大学生程序设计邀请赛 C:小花梨判连通的主要内容,如果未能解决你的问题,请参考以下文章
“盛大游戏杯”第15届上海大学程序设计联赛夏季赛暨上海高校金马五校赛 C
“科大讯飞杯”第18届上海大学程序设计联赛春季赛暨高校网络友谊赛(C~D)
“盛大游戏杯”第15届上海大学程序设计联赛夏季赛暨上海高校金马五校赛 L 零件组装 状态压缩+预处理优化+枚举子集