L2-007. 家庭房产
使用并查集
参考:http://blog.csdn.net/sinat_30126425/article/details/51901934
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define max 10010;
int visit[10001], symbol[10001];
int unionStorage[10001];
struct housing
{
double housingUnit;
double housingArea;
int id;
int num;
housing()
{
id = -1;
}
};
void initializer()
{
for(int i=0; i<10001; i++)
unionStorage[i] = i;
}
int findRoot(int id)
{
if(id!=unionStorage[id])
return findRoot(unionStorage[id]);
else
return id;
}
bool compare(housing a, housing b)
{
if(a.housingArea!=b.housingArea)
return a.housingArea > b.housingArea;
else
return a.id < b.id;
}
void unionOperator(int a, int b)
{
int x = findRoot(a);
int y = findRoot(b);
if(x!=y)
{
if(x>y)
unionStorage[x] = y; //the smaller number is father of bigger number
else
unionStorage[y] = x;
}
}
int main()
{
housing first[1001], stastics[10001], second[1001];
initializer();
memset(visit, 0, sizeof(visit));
memset(symbol, 0, sizeof(symbol));
int n, temp1, temp2, k, child; //k is the number of children
cin >> n;
for(int i=0; i<n; i++)
{
cin >> first[i].id >> temp1 >> temp2;
visit[first[i].id] = 1;
if(temp1!=-1)
{
unionOperator(temp1, first[i].id);
visit[temp1] = 1;
}
if(temp2!=-1)
{
unionOperator(temp2, first[i].id);
visit[temp2] = 1;
}
cin >> k;
for(int j=0; j<k; j++)
{
cin >> child;
if(child!=-1)
{
unionOperator(child, first[i].id);
visit[child] = 1;
}
}
cin >> first[i].housingUnit >> first[i].housingArea;
}
int memory = 0;
for(int i=0; i<n; i++) //统计,一个集合中所有的元素,将房产面积和个数相加
{
int id = findRoot(first[i].id);
if(stastics[id].id != id)
symbol[memory++] = id;
stastics[id].id = id;
stastics[id].housingUnit +=first[i].housingUnit; //前i个节点都是数据
stastics[id].housingArea +=first[i].housingArea; //统计前i个节点
}
for(int i=0; i<10000; i++)
{
if(visit[i])
{
stastics[findRoot(i)].num++; //对于出现过的每一个成员,找到根,为家庭成员的数量加1
}
}
int housingNumber = 0; //家庭个数
for(int i=0; i<memory; i++) //这里和原作者有少许区别,原作者使用symbol数组来标记只有根节点才进行以下运算,这里使用symbol数组记录了所有的根节点,直接进行运算,避免了遍历0-10000才能找出所有的根节点
{
double x = (double)stastics[symbol[i]].num;
second[housingNumber].housingUnit = stastics[symbol[i]].housingUnit / x;
second[housingNumber].housingArea = stastics[symbol[i]].housingArea / x;
second[housingNumber].id = symbol[i];
second[housingNumber++].num = (int)x;
}
sort(second, second+housingNumber, compare);
cout << housingNumber << endl;
for(int i=0; i<housingNumber; i++)
{
printf("%04d %d %0.3lf %0.3lf\n", second[i].id, second[i].num, second[i].housingUnit, second[i].housingArea);
}
return 0;
}
代码2:参考自上边提供的链接,完全抄过来的,有注释
/* *********************************************** Author :yzkAccepted Created Time :2016/7/13 20:28:02 TASK :ggfly.cpp LANG :C++ ************************************************ */ #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <vector> #include <queue> #include <set> #include <map> #include <string> #include <cmath> #include <cstdlib> #include <ctime> #include <stack> using namespace std; const int maxn=11000; int vis[maxn],m[maxn]; int p[10010]; //the union is represent by array,four didit number so the capacity of array i struct node{ double ans1,ans2; int id,num; }; bool cmp(node a,node b){ if(a.ans2!=b.ans2) return a.ans2>b.ans2; //per capita real estate area from biggest to small return a.id<b.id; //成员编号由小到大 } void init(){ for(int i=0;i<=10000;i++) //初始化p[i]; p[i]=i; } int find(int x) //find operator { if(x==p[x]) return x; else return p[x]=find(p[x]); //recursive } void un(int a,int b){ int x=find(a); int y=find(b); if(x!=y){ //if x = y,this is root node if(x>y) p[x]=y; //y become the father of x else p[y]=x; //x become the father of y } } int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); int i,j,n; node a[10005]; node b[10005]; node mul[10005]; cin>>n; init(); //数组初始化p[i]==i memset(vis,0,sizeof(vis)); memset(m,0,sizeof(m)); for(i=0;i<n;i++) { int p1,p2,d,k; cin>>a[i].id>>p1>>p2; vis[a[i].id]=1; //表示这个人员已经访问过 if(p1!=-1){ // parent is still alive un(p1,a[i].id); //union p1 and a[i].id vis[p1]=1; //p1 is already visited } if(p2!=-1){ un(p2,a[i].id); vis[p2]=1; } cin>>k; while(k--){ cin>>d; if(d!=-1){ un(a[i].id,d); vis[d]=1; } } cin>>a[i].ans1>>a[i].ans2; } for(i=0;i<n;i++){ int id=find(a[i].id); mul[id].id=id; //get a[i] root mul[id].ans1+=a[i].ans1; //summation of housing units mul[id].ans2+=a[i].ans2; //summation of housing area } for(i=0; i<10000; i++) if(vis[i]) //i node is visited, { mul[find(i)].num++; //the root node of i number's num +1 } int cnt=0; for(i=0;i<10000;i++){ if(vis[i]){ int id=find(i); if(!m[id]){ m[id]=1; double x=double(mul[id].num); //convert the person number of house from int to double b[cnt].ans1=mul[id].ans1*1.0/x; b[cnt].ans2=mul[id].ans2*1.0/x; b[cnt].id=id; b[cnt++].num=int(x); } } } cout<<cnt<<endl; sort(b,b+cnt,cmp); for(i=0;i<cnt;i++) printf("%04d %d %.3lf %.3lf\n",b[i].id,b[i].num,b[i].ans1,b[i].ans2); return 0; }

浙公网安备 33010602011771号