据预测,大约在100亿年后,狮子座星系将与银河系发生碰撞,两个星系的碰撞将会合并两个星系,但是没有2个星球会相撞。现在某科学家得到两个星系合并后的结果,一些二维平面上的点,但是不知道那些星球属于银河系,已知如果两个星球属于同一个星系,那么他们之间的距离大于5光年,这边的距离指的是欧几里得距离,即(x1,y1)与(x2,y2)的距离为sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2))。现在想请你帮忙把合并后的结果分成2个集合,一个属于银河系,一个属于狮子座星系,由于集合划分的方案可能有多种,现在想知道最多有多少个星球可能属于银河系。(可以所有星球都属于银河系)
例如:如下图有6个点,你可以有以下4中划分{{1, 2, 4, 5}, {3, 6}}; {{1, 2, 3, 4}, {5, 6}}; {{1, 4,5}, {2, 3, 6}}; {{1, 3, 4}, {2, 5, 6}} ,那么可以采用第一种划分{1,2,4,5} 都属于银河系,答案为4.
#include <cstdio> #include <iostream> #include <algorithm> #include <queue> #include <stack> #include <cstdlib> #include <cmath> #include <set> #include <map> #include <vector> #include <cstring> #define INF 100000000 using namespace std; struct node{ int x,y; bool operator < (const node & a)const { return x < a.x; } }; node a[50005]; vector<int> vec[50005]; int cx[50005]; int cy[50005]; int visit[50005]; int n; int path(int u){ int cc = vec[u].size(); for(int i = 0;i < cc;i++){ int v = vec[u][i]; if(!visit[v]){ visit[v] = 1; if(cy[v] == -1 || path(cy[v])){ cy[v] = u; cx[u] = v; return 1; } } } return 0; } int color[50005]; int flag; int maxmatch(int u){ queue<int> que; color[u] = 1; que.push(u); vector<int> va; va.push_back(u); while(!que.empty()){ int t = que.front(); que.pop(); int cc = vec[t].size(); for(int i = 0;i < cc;i++){ int v = vec[t][i]; if(color[v] == -1){ color[v] = (color[t] + 1)%2; if(color[v]){ va.push_back(v); } que.push(v); } else{ if(color[v] == color[t]){ flag = 1; } } } } int cc = va.size(); int res = 0; for(int i = 0;i < cc;i++){ int v = va[i]; if(cx[v] == -1){ memset(visit,0,sizeof(visit)); res += path(v); } } return res; } int d(int i,int j){ return (a[i].x - a[j].x)*(a[i].x - a[j].x) + (a[i].y - a[j].y)*(a[i].y - a[j].y); } int main(){ while(cin >> n){ for(int i = 0;i < n;i++){ scanf("%d%d",&a[i].x,&a[i].y); vec[i].clear(); } sort(a,a+n); for(int i = 0;i < n;i++){ for(int j = i+1;a[j].x - a[i].x <= 5&& j < n;j++){ if(d(i,j) <= 25){ vec[i].push_back(j); vec[j].push_back(i); } } } int tm = 0; memset(cx,-1,sizeof(cx)); memset(cy,-1,sizeof(cy)); memset(color,-1,sizeof(color)); flag = 0; for(int i = 0;i < n && !flag;i++){ if(vec[i].size()){ if(color[i] == -1) tm += maxmatch(i); } } if(flag){ cout << -1 << endl; } else{ cout << (n-tm) << endl; } } return 0; }
原文地址:http://blog.csdn.net/qq_24667639/article/details/45568099