华师一附中OI组
标题:
P2078 朋友
[打印本页]
作者:
admin
时间:
2018-7-27 22:44
标题:
P2078 朋友
题目背景
小明在A公司工作,小红在B公司工作。
https://www.luogu.org/problemnew/show/P2078
题目描述
这两个公司的员工有一个特点:一个公司的员工都是同性。
A公司有N名员工,其中有P对朋友关系。B公司有M名员工,其中有Q对朋友关系。朋友的朋友一定还是朋友。
每对朋友关系用两个整数(Xi,Yi)组成,表示朋友的编号分别为Xi,Yi。男人的编号是正数,女人的编号是负数。小明的编号是1,小红的编号是-1.
大家都知道,小明和小红是朋友,那么,请你写一个程序求出两公司之间,通过小明和小红认识的人最多一共能配成多少对情侣。(包括他们自己)
输入输出格式
输入格式:
第1行,4个空格隔开的正整数N,M,P,Q。
之后P行,每行两个正整数Xi,Yi。
之后Q行,每行两个负整数Xi,Yi。
输出格式:
一行,一个正整数,表示通过小明和小红认识的人最多一共能配成多少对情侣。(包括他们自己)
输入输出样例
输入样例#1:
4 3 4 2
1 1
1 2
2 3
1 3
-1 -2
-3 -3
输出样例#1:
2
说明
对于30%数据,N,M<=100,P,Q<=200
对于80%数据,N,M<=4000,P,Q<=10000.
对于全部数据,N,M<=10000,P,Q<=20000。
作者:
吴语林
时间:
2018-7-28 07:46
#include <algorithm>
#include <iostream>
#include <cmath>
#include <cstring>
#include <map>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <cstdio>
#include <cstdlib>
using namespace std;
int fa[55000],p,q,x,y,n,m,all1=0,all2=0;
int getf(int u)
{
if(fa[u]==u)
return u;
int temp=getf(fa[u]);
fa[u]=temp;
return temp;
}
int main()
{
scanf("%d%d%d%d",&n,&m,&p,&q);
for(int i=1;i<=n+m;i++)
fa[i]=i;
for(int i=1;i<=p;i++)
{
scanf("%d%d",&x,&y);
int t1=getf(x),t2=getf(y);
if(t1!=t2)
fa[t1]=t2;
}
for(int i=1;i<=q;i++)
{
scanf("%d%d",&x,&y);
int t1=getf(n-x),t2=getf(n-y);
if(t1!=t2)
fa[t1]=t2;
}
for(int i=1;i<=n;i++)
if(getf(i)==getf(1))
all1++;
for(int i=n+1;i<=n+m;i++)
if(getf(i)==getf(n+1))
all2++;
printf("%d",min(all1,all2));
return 0;
}
复制代码
作者:
黄煦喆
时间:
2018-7-28 08:53
本帖最后由 黄煦喆 于 2018-7-28 09:10 编辑
#include<iostream>
using namespace std;
int n,m,p,q,ans1,ans2;
int par[20001];
int f(int a)
{
while(par[a]!=par[par[a]])par[a]=par[par[a]];
return par[a];
}
void merge(int a,int b)
{
int r1=f(a);
int r2=f(b);
if(r1==r2)return;
else par[r1]=r2;
}
int main()
{
cin>>n>>m>>p>>q;
for(int i=1;i<=n+m;i++)par[i]=i;
int x,y;
for(int i=1;i<=p;i++)
{
cin>>x>>y;
merge(x,y);
}
for(int i=1;i<=q;i++)
{
cin>>x>>y;
merge(-x+n,-y+n);
}
for(int i=1;i<=n;++i)
if(f(i)==f(1))
ans1++;
for(int i=n+1;i<=n+m;++i)
if(f(i)==f(n+1))
ans2++;
cout<<min(ans1,ans2);
return 0;
}
复制代码
作者:
walk_alone
时间:
2018-7-29 20:13
#include <cstdio>
#include <algorithm>
#include <map>
using namespace std;
map<int,int> father;
int getfather(int x)
{
if(x==father[x])
return x;
return father[x]=getfather(father[x]);
}
int main()
{
int n,m,p,q,a,b,sum1=0,sum2=0;
scanf("%d%d%d%d",&n,&m,&p,&q);
for(int i=-m;i<=n;i++)
father[i]=i;
for(int i=1;i<=p+q;i++)
{
scanf("%d%d",&a,&b);
father[getfather(a)]=getfather(b);
}
for(int i=-m;i<=-1;i++)
if(getfather(i)==getfather(-1))
sum1++;
for(int i=1;i<=n;i++)
if(getfather(i)==getfather(1))
sum2++;
printf("%d",min(sum1,sum2));
}
复制代码
作者:
张笑宇
时间:
2018-7-30 10:22
#include<iostream>
using namespace std;
int n,m,p,q;
const int mx=10010;
int par[mx][3],i;///par[mx][1]是男
int getpar(int a,int x)
{
///找根节点
if (par[a][x]!=a)
par[a][x]=getpar(par[a][x],x);
return par[a][x];
}
void merge_(int a,int b,int x)
{
///合并a,b所在集合
par[getpar(a,x)][x]=getpar(b,x);
return;
}
int main()
{
cin>>n>>m>>p>>q;
for (i=1; i<=n; i++) par[i][1]=i;
for (i=1; i<=m; i++) par[i][2]=i;
for (i=1; i<=p; i++)
{
int a,b;
cin>>a>>b;
merge_(a,b,1);
}
for (i=1; i<=q; i++)
{
int a,b;
cin>>a>>b;
a=-a,b=-b;
merge_(a,b,2);
}
int ansa=0,ansb=0;
for (i=1; i<=n; i++)
if (getpar(i,1)==getpar(1,1)) ansa++;
for (i=1; i<=m; i++)
if (getpar(i,2)==getpar(1,2)) ansb++;
cout<<min(ansa,ansb);
return 0;
}
复制代码
作者:
ZMQ
时间:
2018-8-6 21:56
提示:
作者被禁止或删除 内容自动屏蔽
欢迎光临 华师一附中OI组 (http://hsyit.cn/)
Powered by Discuz! X3.2