P13017 [GESP202506 七级] 线图
题目
传送门
思路
我们观察可以发现新建的这个图的结点是以边为结点,观察题目可以发现只要这个图任意两个结点的u或者v相等,那么我们就可以连接这两个结点。
怎么统计连接的条数?
我们可以遍历每一条边,然后寻找与他的u或者v相等的边,如何ans++,最后记得把ans/2。但是这样的时间复杂度达到了O(m^2),直接TLE。
优化
我们发现只要寻找重复出现的结点即可,所以我们可以统计所有边的u和v的数量,然后分别相加即可。
细节
- ans要开long long
- 每次相加之前都要减一
代码
有注释
#include<bits/stdc++.h>
using namespace std;
int n,m,cnt[100005];
struct u{
int u,v;
}a[100005];
long long ans=0;
int main(){
cin>>n>>m;
for(int i=1;i<=m;i++){
cin>>a[i].u>>a[i].v;
cnt[a[i].u]++;//统计
cnt[a[i].v]++;
}
for(int i=1;i<=m;i++){
cnt[a[i].u]--;//避免重复统计
cnt[a[i].v]--;
ans+=cnt[a[i].u]+cnt[a[i].v];//相加
}
cout<<ans;
return 0;
}
无注释
#include<bits/stdc++.h>
using namespace std;
int n,m,cnt[100005];
struct u{
int u,v;
}a[100005];
long long ans=0;
int main(){
cin>>n>>m;
for(int i=1;i<=m;i++){
cin>>a[i].u>>a[i].v;
cnt[a[i].u]++;
cnt[a[i].v]++;
}
for(int i=1;i<=m;i++){
cnt[a[i].u]--;
cnt[a[i].v]--;
ans+=cnt[a[i].u]+cnt[a[i].v];
}
cout<<ans;
return 0;
}
另一个版本
我们枚举每一个结点,然后统计它相连的结点的数量,最后n*(n-1)/2即可
for(int i=1;i<=n;i++){
int s=v[i].size();
ans+=s*(s-1)/2;
}

浙公网安备 33010602011771号