这道题可把我搞惨了
我自己踩的坑,大家可以借鉴一下
1.短电话的时长,需要加起来,因为存在两个不止一次通话。
2.只有是短电话的人回电才计数。
3.集合要用并查集
AC 25分
#include <iostream>
#include <vector>
#include <string>
#include <cmath>
#include <algorithm>
#include <queue>
#include <cstdio>
#include <cctype>
#include <unordered_map>
#include <map>
#include <cstring>
#include <set>
using namespace std;
const int N = 1005;
int G[N][N]={0};
int root[N];
int find(int x){
if(x != root[x]) root[x] = find(root[x]);
return root[x];
}
int main() {
int K, n, m, u, v, w;
cin>>K>>n>>m;
for(int i = 0; i < m; i++){
cin>>u>>v>>w;
G[u][v] += w;
}
vector<int> vt;
for(int i = 1; i <= n; i++){
int call = 0, recall = 0;
for(int j = 1; j <= n; j++){
if(G[i][j] != 0 && G[i][j] <= 5){ //从打短电话中计算回电话的人小于20%
call++;
if(G[j][i] != 0) recall++;
}
}
double t = recall*1.0/call;
if(call > K && t <= 0.2){ //是嫌疑人
vt.push_back(i);
}
}
for(int i = 1; i <= n; i++){
root[i] = i;
}
if(vt.size()==0) cout<<"None"<<endl;
else if(vt.size()==1) cout<<vt[0]<<endl;
else{
map<int, vector<int>> mp;
//并查集
for(int i = 0; i < vt.size(); i++){
for(int j = i+1; j < vt.size(); j++){
int a = vt[i], b = vt[j];
if(G[a][b] && G[b][a]){
int u = find(a);
int v = find(b);
if(u != v){
if(u > v) swap(u, v); //始终让u当小的
root[v] = u;
}
}
}
}
for(int i = 0; i < vt.size(); i++){
int L = find(vt[i]);
mp[L].push_back(vt[i]);
}
//输出
for(auto x: mp){
int tag = 0;
for(auto c: x.second){
if(!tag){
cout<<c;
tag = 1;
}else cout<<" "<<c;
}
cout<<endl;
}
}
return 0;
}
DFS
21分
有毒!
#include <iostream>
#include <vector>
#include <string>
#include <cmath>
#include <algorithm>
#include <queue>
#include <cstdio>
#include <cctype>
#include <unordered_map>
#include <map>
#include <cstring>
#include <set>
using namespace std;
const int N = 1005;
int G[N][N]={0};
int root[N], vis[N]={0};
vector<int> ve, vt;
void dfs(int x){
vis[x] = 1;
ve.push_back(x);
for(auto i: vt){
if(!vis[i] && G[i][x] && G[x][i]) dfs(i);
}
}
int main() {
int K, n, m, u, v, w;
cin>>K>>n>>m;
for(int i = 0; i < m; i++){
cin>>u>>v>>w;
G[u][v] = + w; //通话时长要累加
}
for(int i = 1; i <= n; i++){
int call = 0, recall = 0;
for(int j = 1; j <= n; j++){
if(G[i][j] != 0 && G[i][j] <= 5){ //从打短电话中计算回电话的人小于20%
call++;
if(G[j][i] != 0) recall++;
}
}
double t = recall*1.0/call;
if(call > K && t <= 0.2){ //是嫌疑人
vt.push_back(i);
}
}
if(vt.size()==0) cout<<"None"<<endl;
else if(vt.size()==1) cout<<vt[0]<<endl;
else{
//用深搜 把一个集合的收集起来
sort(vt.begin(), vt.end());
for(auto a: vt){
ve.clear();
if(!vis[a]) dfs(a);
sort(ve.begin(), ve.end());
for(int i = 0; i < ve.size(); i++){
cout<<ve[i];
if(i != ve.size()-1) cout<<" ";
else cout<<endl;
}
}
}
return 0;
}