码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 5486 Difference of Clustering 图论

时间:2016-06-20 23:50:33      阅读:170      评论:0      收藏:0      [点我收藏+]

标签:

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=5486

题意:

给你每个元素一开始所属的集合和最后所属的集合,问有多少次集合的分离操作,并操作和不变操作。

分离:[m1,m2,m3]->[m1],[m2],[m3]

合并:分离的逆操作

不变:[m1,m2,m3]->[m1,m2,m3]

题解;

以集合为单位建图,(一个元素从集合s1到s2则建一条边连接集合s1,s2,注意要删除重边)

然后对于每个点,与它相邻的点如果入度都为1,则为分离操作,

把图转置,再跑一遍分离就是合并。

如果一个集合只有一条连向自己的边,那么说明它是1:1操作。

代码:

 #include<iostream>
#include<cstdio>
#include<map>
#include<vector>
#include<algorithm>
#include<cstring>
using namespace std;

const int maxn = 1e6 + 10;

int n,_max;
map<pair<int, int>, int> mp;
vector<int> G[maxn], G2[maxn];
int in[maxn], in2[maxn];

void init() {
	_max = -1;
	mp.clear();
	for (int i = 0; i <maxn; i++) G[i].clear(),G2[i].clear();
	memset(in, 0, sizeof(in));
	memset(in2, 0, sizeof(in2));
}

int main() {
	int tc,kase=0;
	scanf("%d", &tc);
	while (tc--) {
		scanf("%d", &n);
		init();
		for (int i = 0; i < n; i++) {
			int u, v;
			_max = max(_max, u);
			_max = max(_max, v);
			scanf("%d%d", &u, &v);
			if (!mp[make_pair(u, v)]) {
				mp[make_pair(u, v)]++;
				G[u].push_back(v);
				in[v]++;
				G2[v].push_back(u);
				in2[u]++;
			}
		}
		int ans1=0, ans2=0,ans3=0;
		for (int i = 0; i <= _max; i++) {
			int su = 1;
			for (int j = 0; j < G[i].size(); j++) {
				int v = G[i][j];
				if (in[v] > 1) { su = 0; break; }
			}
			if (su) {
				if (G[i].size() == 1) ans3++;
				else if(G[i].size()>1) ans2++;
			}
		}
		for (int i = 0; i <= _max; i++) {
			int su = 1;
			for (int j = 0; j < G2[i].size(); j++) {
				int v = G2[i][j];
				if (in2[v] > 1) { su = 0; break; }
			}
			if (su) {
				if (G2[i].size() == 1);
				else if(G2[i].size()>1) ans1++;
			}
		}
		printf("Case #%d: %d %d %d\n", ++kase, ans2,ans1, ans3);
	}
	return 0;
}

HDU 5486 Difference of Clustering 图论

标签:

原文地址:http://www.cnblogs.com/fenice/p/5602152.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!