P10378 [GESP202403 七级] 交流问题
题目
思路
看了看题解区,大部分dalao都是用二分图解决的,可是煮波不会QWQ
我于是在地上打了1h的滚加上看了看题解区里发现还可以用dfs解决
实现方法
就是遍历每个没有被标记的结点,把他们标记成true,然后遍历与他相邻的连通块,也就是DFS,A和B的学生数可以用奇偶性来判断,具体见代码。
代码
有注释
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,m,ans1=0,ans2=0,cnt1=0,cnt2=0;
vector<int>v[N];
bool f[N];
void dfs(int x,int s){
if(v[x].size()==0)return;
for(int i=0;i<v[x].size();i++){//遍历相邻的边
if(!f[v[x][i]]){//如果没被遍历过
f[v[x][i]]=true;//标记为true
if(s%2==1){//借助奇偶性判断
cnt2++;
}
else{//同理
cnt1++;
}
dfs(v[x][i],s+1);//继续以他为起始点遍历
}
}
}
int main(){
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
cin>>n>>m;
for(int i=1;i<=m;i++){
int x,y;
cin>>x>>y;
v[x].push_back(y);
v[y].push_back(x);
}
for(int i=1;i<=n;i++){
if(!f[i]){//没被标记过
f[i]=true;
cnt1=cnt2=0;//初始化
cnt1++;//第一个结点
dfs(i,1);//DFS
ans1+=min(cnt1,cnt2);//至少的取最小的
ans2+=max(cnt1,cnt2);//至多的取最大的
}
}
cout<<ans1<<' '<<ans2;
return 0;
}
无注释
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,m,ans1=0,ans2=0,cnt1=0,cnt2=0;
vector<int>v[N];
bool f[N];
void dfs(int x,int s){
if(v[x].size()==0)return;
for(int i=0;i<v[x].size();i++){
if(!f[v[x][i]]){
f[v[x][i]]=true;
if(s%2==1){
cnt2++;
}
else{
cnt1++;
}
dfs(v[x][i],s+1);
}
}
}
int main(){
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
cin>>n>>m;
for(int i=1;i<=m;i++){
int x,y;
cin>>x>>y;
v[x].push_back(y);
v[y].push_back(x);
}
for(int i=1;i<=n;i++){
if(!f[i]){
f[i]=true;
cnt1=cnt2=0;
cnt1++;
dfs(i,1);
ans1+=min(cnt1,cnt2);
ans2+=max(cnt1,cnt2);
}
}
cout<<ans1<<' '<<ans2;
return 0;
}

浙公网安备 33010602011771号