您的位置:首页 > 科技 > IT业 > [USACO20OPEN] Favorite Colors G

[USACO20OPEN] Favorite Colors G

2024/9/22 3:16:58 来源:https://blog.csdn.net/2302_81761369/article/details/142186467  浏览:    关键词:[USACO20OPEN] Favorite Colors G

[USACO20OPEN] Favorite Colors G

思路:

一个点的儿子如果有多个的话,那么就合并他们,因此可以想到用启发式合并不断合并两个点。

代码:

#include <bits/stdc++.h>
#define int long long
#define fi first
#define se second
using namespace std;
const int inf = 0x3f3f3f3f3f3f3f;
const int N = 2e5+5;
int n,m;
vector<int>g[N];
vector<int>son[N];
int color[N];
int pre[N];
int idx = 0;
queue<int>q;int root(int x){return pre[x] = (pre[x] == x)?x:root(pre[x]);
}void merge(int x,int y){x = root(x);y = root(y);if(son[x].size()<son[y].size())swap(x,y);//儿子多的合并儿子少的for(const auto &i:g[y]){g[x].push_back(i);}for(const auto &i:son[y]){pre[i] = x;son[x].push_back(i);}if(g[x].size()>1)q.push(x);}void solve(){cin>>n>>m;for(int i=1;i<=m;i++){int x,y;cin>>x>>y;g[x].push_back(y);}for(int i=1;i<=n;i++){pre[i] = i;son[i].push_back(i);if(g[i].size()>1)q.push(i);}while(!q.empty()){int fa = q.front();q.pop();while(g[fa].size()>1){//如果儿子>=2个那么就合并int x = g[fa][0];int y = g[fa][1];g[fa].erase(g[fa].begin());if(root(x)!=root(y)){merge(x,y);}}}for(int i=1;i<=n;i++){if(!color[root(i)]){color[root(i)] = ++idx;}cout<<color[root(i)]<<"\n";}}signed main(){ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);int T=1;//cin>>T;while(T--){solve();}return 0;
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com