# 网络分析 **问题描述** 小明正在做一个网络实验。 他设置了 n 台电脑,称为节点,用于收发和存储数据。初始时,所有节点都是独立的,不存在任何连接。 小明可以通过网线将两个节点连接起来,连接后两个节点就可以互相通信了。两个节点如果存在网线连接,称为相邻。 小明有时会测试当时的网络,他会在某个节点发送一条信息,信息会发送到每个相邻的节点,之后这些节点又会转发到自己相邻的节点,直到所有直接或间接相邻的节点都收到了信息。所有发送和接收的节点都会将信息存储下来。 一条信息只存储一次。 给出小明连接和测试的过程,请计算出每个节点存储信息的大小。 **输入格式** 输入的第一行包含两个整数 n, m,分别表示节点数量和操作数量。节点从1 至 n 编号。 接下来 m 行,每行三个整数,表示一个操作。 如果操作为 1 a b,表示将节点 a 和节点 b 通过网线连接起来。当 a = b时,表示连接了一个自环,对网络没有实质影响。 如果操作为 2 p t,表示在节点 p 上发送一条大小为 t 的信息。 **输出格式** 输出一行,包含 n 个整数,相邻整数之间用一个空格分割,依次表示进行完上述操作后节点 1 至节点 n 上存储信息的大小。 **样例输入** ``` 4 8 1 1 2 2 1 10 2 3 5 1 4 1 2 2 2 1 1 2 1 2 4 2 2 1 ``` **样例输出** ``` 13 13 5 3 ``` **评测用例规模与约定** ``` 对于 30% 的评测用例,1 ≤ n ≤ 20,1 ≤ m ≤ 100。 对于 50% 的评测用例,1 ≤ n ≤ 100,1 ≤ m ≤ 1000。 对于 70% 的评测用例,1 ≤ n ≤ 1000,1 ≤ m ≤ 10000。 对于所有评测用例,1 ≤ n ≤ 10000,1 ≤ m ≤ 100000,1 ≤ t ≤ 100。 ``` 以下选项错误的是? ## aop ### before ```cpp #include using namespace std; ``` ### after ```cpp ``` ## 答案 ```cpp int main() { int n = 0; int m = 0; cin >> n; cin >> m; int ar[n + 1][n + 1]; for (int i = 0; i < n + 1; i++) for (int j = 0; j < n + 1; j++) ar[i][j] = 0; bool arJudge[n + 1]; for (int i = 0; i < n + 1; i++) arJudge[i] = 0; vector v(n, 0); for (int i = 0; i <= n; ++i) { for (int j = 0; j <= n; ++j) { ar[i][j] = 0; } } int a = 0, b = 0, c = 0; for (int i = 0; i < m; ++i) { cin >> a; cin >> b; cin >> c; if (a == 1) { if (ar[b][c] == 0) { ar[b][c] = 1; } if (ar[c][b] == 0) { ar[c][b] = 1; } } if (a == 2) { queue que; que.push(b); while (!que.empty()) { int size = que.size(); for (int i = 0; i < size; ++i) { int temp = que.front(); que.pop(); if (arJudge[temp] == 0) { v[temp - 1] += c; arJudge[temp] = 1; } for (int j = 1; j <= n; ++j) { if (ar[temp][j] != 0) { que.push(j); } } } } } for (int i = 0; i <= n; ++i) { arJudge[i] = 0; } } for (int i = 1; i <= n; ++i) { for (int j = 1; j <= n; ++j) { cout << ar[i][j] << " "; } cout << endl; } for (int i = 0; i < n; ++i) { cout << v[i] << " "; } cout << endl; return 0; } ``` ## 选项 ### A ```cpp int const N = 10010; using namespace std; int n, m; int i, j, k; int num[N]; int f[N]; int r[N]; void init() { for (i = 1; i <= n; i++) { f[i] = i; r[i] = 1; } } int find(int x) { return f[x] == x ? x : (f[x] = find(f[x])); } void send(int x, int y) { int tempx, tempy; tempx = find(x); tempy = find(y); if (r[tempx] >= r[tempy]) { f[tempy] = tempx; } else { f[tempx] = tempy; } if (r[tempx] == r[tempy] && tempx != tempy) { r[tempx]++; } } void count(int x, int y) { int tempx; tempx = find(x); for (i = 1; i <= n; i++) { if (tempx == find(i)) { num[i] += y; } } } int main() { cin >> n >> m; init(); while (m--) { int x, y, z; cin >> x >> y >> z; if (x == 1) { send(y, z); } if (x == 2) { count(y, z); } } for (i = 1; i <= n; i++) { cout << num[i] << " "; } return 0; } ``` ### B ```cpp const int N = 10010; int p[N], d[N]; int find(int x) { if (p[x] == x || p[p[x]] == p[x]) return p[x]; int r = find(p[x]); d[x] += d[p[x]]; p[x] = r; return r; } int main() { int n, m; cin >> n >> m; for (int i = 1; i <= n; i++) p[i] = i; while (m--) { int t, a, b; cin >> t >> a >> b; if (t == 1) { a = find(a), b = find(b); if (a != b) { d[a] -= d[b]; p[a] = b; } } else { a = find(a); d[a] += b; } } for (int i = 1; i <= n; i++) if (i == find(i)) cout << d[i] << " "; else cout << d[i] + d[find(i)] << " "; cout << endl; return 0; } ``` ### C ```cpp const int maxn = 10005; int a[maxn][maxn]; int dfs_vis[maxn]; int n, m; struct Node { int data; } Point[maxn]; void DFS(int a[maxn][maxn], int x, int y) { Point[x].data += y; dfs_vis[x] = 1; for (int i = 1; i <= n; i++) { if (a[x][i] == 1 && dfs_vis[i] == 0) { DFS(a, i, y); } } } int main() { cin >> n >> m; cin.get(); for (int i = 1; i <= m; i++) { int flag, x1, x2; scanf("%d %d %d", &flag, &x1, &x2); if (flag == 1) { a[x1][x2] = a[x2][x1] = 1; } else if (flag == 2) { memset(dfs_vis, 0, sizeof(dfs_vis)); DFS(a, x1, x2); } } for (int i = 1; i <= n; ++i) { cout << Point[i].data << " "; } return 0; } ```