✏️ 纠错
第 136 题 / 共 155 题

题目描述

给定由 n 个结点与 m 条边构成的简单无向图 G,结点依次以 1,2,…,n 编号。简单无向图意味着 G 中不包含重边与自环。G 的线图 L(G) 通过以下方式构建:

  • 初始时线图 L(G) 为空。

  • 对于无向图 G 中的一条边,在线图 L(G) 中加入与之对应的一个结点。

  • 对于无向图 G 中两条不同的边 (u1​,v1​),(u2​,v2​),若存在 G 中的结点同时连接这两条边(即 u1​,v1​ 之一与 u2​,v2​ 之一相同),则在线图 L(G) 中加入一条无向边,连接 (u1​,v1​),(u2​,v2​) 在线图中对应的结点。

请你求出线图 L(G) 中所包含的无向边的数量。

输入格式

第一行,两个正整数 n,m,分别表示无向图 G 中的结点数和边数。

接下来 m 行,每行两个正整数 ui​,vi​,表示 G 中连接 ui​,vi​ 的一条无向边。

输出格式

输出共一行,一个整数,表示线图 L(G) 中所包含的无向边的数量。

输入输出样例

输入 #1

5 4
1 2
2 3
3 1
4 5

输出 #1

3

输入 #2

5 10
1 2
1 3
1 4
1 5
2 3
2 4
2 5
3 4
3 5
4 5

输出 #2

30

说明/提示

【样例解释 #1】

【数据范围】

对于 60% 的测试点,保证 1≤n≤500,1≤m≤500。

对于所有测试点,保证 1≤n≤105,1≤m≤105。

📝 题目解析

【题目大意】给定一个简单无向图G(无自环和重边),要求构造它的线图L(G),并计算L(G)中的边数。线图的构造规则:

原图G的每条边对应线图L(G)的一个顶点。

若原图G中两条边共享一个公共顶点,则在线图L(G)中对应的两个顶点之间连一条边。

【考纲知识点】

图的定义及遍历

【解题思路】

线图性质理解:线图L(G)的边数等于原图G中所有共享顶点的边对数。即对于原图G中的每个顶点v,计算其度数d(v),然后贡献C(d(v),2)(即d(v)选2的组合数)到总边数中。

数学转化:总边数= Σ[C(d(v),2)],其中d(v)是顶点v的度数。这可以简化为Σ[d(v)*(d(v)-1)/2]。

解题步骤:

1.先统计每个顶点的度数d(v)。

2.遍历所有顶点,累加每个顶点的C(d(v),2)。

【参考程序】
#include <cstdio>
using namespace std;

const int N = 1e5 + 5;

int n, m, deg[N];
long long ans;

int main() {
    scanf("%d%d", &n, &m);
    while (m--) {
        int u, v;
        scanf("%d%d", &u, &v);
        // 每条边会增加两个端点的度数
        deg[u]++;
        deg[v]++;
    }
    // 对每个节点,计算其度数对应的边组合数并累加
    for (int i = 1; i <= n; i++)
        ans += (long long)deg[i] * (deg[i] - 1) / 2;
    printf("%lld\n", ans);
    return 0;
}