L2-007 家庭房產 (25 分)
給定每個人的家庭成員和其自己名下的房產,請你統計出每個家庭的人口數、人均房產面積及房產套數。
輸入格式:
輸入第一行給出一個正整數N(≤1000),隨後N行,每行按下列格式給出一個人的房產:
其中編號
是每個人獨有的一個4位數的編號;父
和母
分別是該編號對應的這個人的父母的編號(如果已經過世,則顯示-1
);k
(0≤k
≤5)是該人的子女的個數;孩子i
是其子女的編號。
輸出格式:
首先在第一行輸出家庭個數(所有有親屬關係的人都屬於同一個家庭)。隨後按下列格式輸出每個家庭的信息:
其中人均值要求保留小數點後3位。家庭信息首先按人均面積降序輸出,若有並列,則按成員編號的升序輸出。
噁心。。。
用並查集合並當前這個人和他的父母以及兒子,合併爲最小的下標
然後再開一個數組去搞會方便一點
#include <iostream>
#include <queue>
#include <map>
#include <cmath>
#include <set>
#include <iomanip>
#include <iomanip>
#include <unordered_set>
#include <cstring>
#include <unordered_map>
#include <algorithm>
using namespace std;
const int maxn=10005;
int n;
int pre[maxn];
struct node
{
int id;
int fa=0,ma=0;
int num=0;
double area=0;
int peo=0;
double areas=0;
}a[maxn],ans[maxn];
int uni(int root)
{
int son,tem;
son=root;
while(root!=pre[root])
{
root=pre[root];
}
while(son!=root)
{
tem=pre[son];
pre[son]=root;
son=tem;
}
return root;
}
void join(int x,int y)
{
x=uni(x);
y=uni(y);
if(x>y)
{
pre[x]=y;
}
else pre[y]=x;
}
bool cmp(node a,node b)
{
if(a.areas==b.areas)
{
return a.id<b.id;
}
return a.areas>b.areas;
}
int main()
{
ios::sync_with_stdio(false);
cin>>n;
int k;
int summ=0;
for(int i=0;i<10000;i++)pre[i]=i;
for(int i=1;i<=n;i++)
{
cin>>a[i].id>>a[i].fa>>a[i].ma>>k;
if(a[i].fa!=-1)
{
join(a[i].fa,a[i].id);
}
if(a[i].ma!=-1)
{
join(a[i].ma,a[i].id);
}
int son;
for(int j=1;j<=k;j++)
{
cin>>son;
join(a[i].id,son);
}
cin>>a[i].num>>a[i].area;
}
int x;
for(int i=1;i<=n;i++)
{
x=uni(a[i].id);//找根節點
ans[x].id=x;
ans[x].area+=a[i].area;
ans[x].num+=a[i].num;
ans[x].fa=-1;
}
//cout<<"summ"<<summ<<endl;
for(int i=0;i<10000;i++)
{
ans[uni(i)].peo++;
if(ans[i].fa==-1){
summ++;
}
}
for(int i=0;i<10000;i++)
{
if(ans[i].fa==-1)
{
ans[i].areas=ans[i].area/ans[i].peo;
}
}
cout<<summ<<endl;
sort(ans,ans+9999,cmp);
for(int i=0;i<summ;i++)
{
cout<<setfill('0')<<setw(4)<<ans[i].id;
cout<<' '<<ans[i].peo<<' ';
cout<<fixed<<setprecision(3)<<(double)ans[i].num/ans[i].peo<<' '
<<ans[i].areas<<endl;
}
return 0;
}
L2-010 排座位 (25 分)
佈置宴席最微妙的事情,就是給前來參宴的各位賓客安排座位。無論如何,總不能把兩個死對頭排到同一張宴會桌旁!這個艱鉅任務現在就交給你,對任何一對客人,請編寫程序告訴主人他們是否能被安排同席。
輸入格式:
輸入第一行給出3個正整數:N
(≤100),即前來參宴的賓客總人數,則這些人從1到N
編號;M
爲已知兩兩賓客之間的關係數;K
爲查詢的條數。隨後M
行,每行給出一對賓客之間的關係,格式爲:賓客1 賓客2 關係
,其中關係
爲1表示是朋友,-1表示是死對頭。注意兩個人不可能既是朋友又是敵人。最後K
行,每行給出一對需要查詢的賓客編號。
這裏假設朋友的朋友也是朋友。但敵人的敵人並不一定就是朋友,朋友的敵人也不一定是敵人。只有單純直接的敵對關係纔是絕對不能同席的。
輸出格式:
對每個查詢輸出一行結果:如果兩位賓客之間是朋友,且沒有敵對關係,則輸出No problem
;如果他們之間並不是朋友,但也不敵對,則輸出OK
;如果他們之間有敵對,然而也有共同的朋友,則輸出OK but...
;如果他們之間只有敵對關係,則輸出No way
。
並查集朋友,因爲朋友的朋友也是朋友,對於敵人直接標記
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e3+5;
int pre[maxn];
set<int>s[maxn];
int uni(int root)
{
int son, tem;
son = root;
while (root != pre[root])
{
root = pre[root];
}
while (son != root)
{
tem = pre[son];
pre[son] = root;
son = tem;
}
return root;
}
int main()
{
ios::sync_with_stdio(false);
int n,m,k;
int x,y,tem;
cin>>n>>m>>k;
for(int i=1;i<=n;i++)
{
pre[i]=i;
}
for(int i=1;i<=m;i++)
{
int xx,yy;
cin>>x>>y>>tem;
if(tem==1)
{
xx=uni(x);
yy=uni(y);
pre[xx]=yy;
}
else
{
s[y].insert(x);
s[x].insert(y);
}
}
for(int i=1;i<=k;i++)
{
cin>>x>>y;
if(!s[x].empty()&&s[x].find(y)!=s[x].end())
{
if(uni(x)!=uni(y))
{
cout<<"No way"<<endl;
}
else cout<<"OK but..."<<endl;
}
else
{
if(uni(x)==uni(y))
{
cout<<"No problem"<<endl;
}
else cout<<"OK"<<endl;
}
}
return 0;
}
L2-013 紅色警戒
並查集一下記錄個數,如果刪除前的個數=刪除後的個數或者刪除前的個數=刪除後的個數-1,那麼刪除這個點就沒有影響
其他情況是有影響的
#include <bits/stdc++.h>
#define quickio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
#define ll long long
int n,m;
const int maxn=5005;
int pre[maxn];
int uni(int x)
{
return x==pre[x]?pre[x]:uni(pre[x]);
}
void join(int x,int y)
{
int xx=uni(x);
int yy=uni(y);
pre[xx]=yy;
}
int main()
{
int u[maxn],v[maxn];
cin>>n>>m;
for(int i=0;i<n;i++)pre[i]=i;
for(int i=1;i<=m;i++)
{
cin>>u[i]>>v[i];
join(u[i],v[i]);
}
int k;
int a;
int num=0;
int new_num=0;
cin>>k;
for(int i=0;i<n;i++)
{
if(pre[i]==i)
{
num++;
}
}
set<int>s;
for(int i=1;i<=k;i++)
{
new_num=0;
cin>>a;
s.insert(a);
for(int j=0;j<n;j++)pre[j]=j;
for(int j=1;j<=m;j++)
{
if(s.find(u[j])!=s.end()||s.find(v[j])!=s.end())
continue;
join(u[j],v[j]);
}
for(int j=0;j<n;j++)
{
if(s.find(j)!=s.end())continue;
if(pre[j]==j)
{
new_num++;
}
}
if(new_num==num||new_num==num-1)
{
cout<<"City "<<a<<" is lost."<<endl;
}
else cout<<"Red Alert: City "<<a<<" is lost!"<<endl;
if((int)s.size()==n)
{
cout<<"Game Over."<<endl;
}
num=new_num;
}
return 0;
}