731 C. Socks

今晚的比赛时间比较合适,就果断注册做了一下。结果真实惨呀。只过了一个题,第二题和第三题比赛的时候思路都是对的,后来比赛结束后判题有些细节没写好。结果WA了。也是太久没刷题的原因了。第三题刚开始是TLE,后来优化了一下。我是用bfs做的,思路通过bfs是将有关系的袜子放在一起,因为这些袜子最后是要涂成同一种颜色的。然后在这堆袜子中,某种颜色的袜子最多,就将其作为这对袜子的最终的颜色。这样保证要涂的次数最少。刚开始TLE是因为在统计某一堆中最多的袜子的时候我为了图省事,直接来了一个200000的数组,结果每次都需要初始化这个数组,因此浪费了很多时间。最后,采取的方法是将这一堆的袜子的颜色排序,这样,相同的颜色就在一起,很好统计。也节省了很多时间。具体实现看代码吧,以后没事还是得多刷题,写代码不能图省事了,得严谨一点。。。

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
#include <vector>
#include <map>

using namespace std;

const int MAX = 200005;

int a[MAX], vis[MAX], tmp[MAX], c[MAX];

vector<int> G[MAX];


void init(){
	for (int i = 0; i<MAX; i++) vis[i] = 1;

	for (int i = 0; i<MAX; i++) G[i].clear();
}

int bfs(int r){
	queue<int> q;
	q.push(r);
	vis[r] = 1;

	int cnt = 0;
	tmp[cnt++] = a[r];

	while(!q.empty()){
		int u = q.front();
		q.pop();

	//	printf("%d ", u);

		for (int i = 0; i<G[u].size(); i++){
			int v = G[u][i];
			if (!vis[v]){
				vis[v] = 1;
				q.push(v);
				tmp[cnt++] = a[v];

			}
		}
	}

	sort(tmp, tmp+cnt);

	int maxn = 0, cc = 1;
	for (int i = 1; i<cnt; i++){
		if (tmp[i] == tmp[i-1]){
			cc++;
		}else{
			maxn = max(maxn, cc);
			cc = 1;

		}

	}
	maxn = max(maxn, cc);
	return (cnt - maxn);
}


int main(){
	int n, m, k;
	while (scanf("%d%d%d", &n,&m, &k) != EOF){

		init();
		for (int i = 1; i<=n; i++){
			scanf("%d", &a[i]);
		}

		int x, y;
		for (int i = 0; i<m; i++){
			scanf("%d%d", &x, &y);
			vis[x] = 0;
			vis[y] = 0;

			G[x].push_back(y);
			G[y].push_back(x);

		}

		int ans = 0;
		for (int i = 1; i<=n; i++) if (!vis[i]){
			ans += bfs(i);
		}

		printf("%d\n", ans);

	}

	return 0;

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值