今天我直接开搞把作业搞定,上题目。
题目背景
小明在 A 公司工作,小红在 B 公司工作。
题目描述
这两个公司的员工有一个特点:一个公司的员工都是同性。
A 公司有 NN 名员工,其中有 PP 对朋友关系。B 公司有 MM 名员工,其中有 QQ 对朋友关系。朋友的朋友一定还是朋友。
每对朋友关系用两个整数 (X_i,Y_i)(Xi,Yi) 组成,表示朋友的编号分别为 X_i,Y_iXi,Yi。男人的编号是正数,女人的编号是负数。小明的编号是 11,小红的编号是 -1−1。
大家都知道,小明和小红是朋友,那么,请你写一个程序求出两公司之间,通过小明和小红认识的人最多一共能配成多少对情侣(包括他们自己)。
输入格式
输入的第一行,包含 44 个空格隔开的正整数 N,M,P,QN,M,P,Q。
之后 PP 行,每行两个正整数 X_i,Y_iXi,Yi。
之后 QQ 行,每行两个负整数 X_i,Y_iXi,Yi。
输出格式
输出一行一个正整数,表示通过小明和小红认识的人最多一共能配成多少对情侣(包括他们自己)。
输入输出样例
输入 #1复制
4 3 4 2 1 1 1 2 2 3 1 3 -1 -2 -3 -3
输出 #1复制
2
出自洛谷: 朋友 - 洛谷
很明显这是一个查并集当然对负数要进行处理,不过题目很好,把条件设置的10分的友好,一个公司只有一个性别那n后面的负的*-1+n不就可以并起来了吗?友好真的是友好。上码
#include<stdio.h>
#include<string.h>
int fa[20100];
int n,m,p,q;
void chu(){
for(int h=1;h<=m+n;h++){
fa[h]=h;
}
}
int find(int a){
if(fa[a]==a)
return a;
else{
fa[a]=find(fa[a]);
return fa[a];
}
}
void heping(int j,int k){
int h=find(fa[j]);
int z=find(fa[k]);
if(h!=z){
fa[h]=z;
}
}
int min(int f,int q){
if(f>q)
return q;
else
return f;
}
int ji=0,jl=0;
void work(int p){
for(int j=1;j<=m+n;j++){
if(find(j)==p){
if(j<=n)
ji++;
else
jl++;
}
}
printf("%d",min(ji,jl));
}
int main(){
int arr[2];
scanf("%d%d%d%d",&n,&m,&p,&q);
chu();
for(int y=0;y<p;y++)
{
scanf("%d%d",&arr[0],&arr[1]);
heping(arr[0],arr[1]);
}
for(int u=0;u<q;u++){
scanf("%d%d",&arr[0],&arr[1]);
heping(-1*arr[0]+n,-1*arr[1]+n);
}
heping(1,1+n);
int h=find(1);
work(h);
return 0;
}
最后只要找祖先为1的就可以了,当然要记录男女,小于等于n的就是男的反之就是女的,取男女生数小的那个。一夫一妻制
欧克 ,下一个。
在JSOI2005夏令营快要结束的时候,很多营员提出来要把整个夏令营期间的资料刻录成一张光盘给大家,以便大家回去后继续学习。组委会觉得这个主意不错!可是组委会一时没有足够的空光盘,没法保证每个人都能拿到刻录上资料的光盘,又来不及去买了,怎么办呢?!
组委会把这个难题交给了LHC,LHC分析了一下所有营员的地域关系,发现有些营员是一个城市的,其实他们只需要一张就可以了,因为一个人拿到光盘后,其他人可以带着U盘之类的东西去拷贝啊!
可是,LHC调查后发现,由于种种原因,有些营员并不是那么的合作,他们愿意某一些人到他那儿拷贝资料,当然也可能不愿意让另外一些人到他那儿拷贝资料,这与我们JSOI宣扬的团队合作精神格格不入!!!
现在假设总共有N个营员(2<=N<=200),每个营员的编号为1~N。LHC给每个人发了一张调查表,让每个营员填上自己愿意让哪些人到他那儿拷贝资料。当然,如果A愿意把资料拷贝给B,而B又愿意把资料拷贝给C,则一旦A获得了资料,则B,C都会获得资料。
现在,请你编写一个程序,根据回收上来的调查表,帮助LHC计算出组委会至少要刻录多少张光盘,才能保证所有营员回去后都能得到夏令营资料?
输入格式
先是一个数N,接下来的N行,分别表示各个营员愿意把自己获得的资料拷贝给其他哪些营员。即输入数据的第i+1行表示第i个营员愿意把资料拷贝给那些营员的编号,以一个0结束。如果一个营员不愿意拷贝资料给任何人,则相应的行只有1个0,一行中的若干数之间用一个空格隔开。
输出格式
一个正整数,表示最少要刻录的光盘数。
输入输出样例
输入 #1复制
5 2 3 4 0 4 5 0 0 0 1 0
输出 #1复制
1
出自洛谷:https://www.luogu.com.cn/problem/P2835
思路一看就是查并集,然后你开心的去写,啪,你没了,你不懂反复检查自己的代码确定自己的查并集没写错。然后你看了一下题目,发现两者之间不一定是双向的于是你痛定思痛把代码进行了整容。最后得出结果,我们只是需要写一个单向关系的查并序就像一条链就可以了,优化的压缩就不要了,ok上马!
#include<stdio.h>
#include<string.h>
int fa[210];
int map[210][210]={0};//记录x是否愿意给y。
int n;
int ans=0;
void chu(){
for(int h=1;h<=n;h++){
fa[h]=h;
}
}
void work(){
for(int p=1;p<=n;p++)
if(fa[p]==p)
ans++;
}
int main(){
int j=1;
scanf("%d",&n);
chu();
for(int y=1;y<=n;y++)
{
while(j>0){
scanf("%d",&j);
if(j!=0)
map[y][j]=1;//表示第y个人愿意给第j个人copy.
}
j=1;
}
for(int f=1;f<=n;f++)
for(int u=1;u<=n;u++)
for(int lp=1;lp<=n;lp++){
if(map[u][f]==1&&map[f][lp]==1)//u愿意给k,k 愿意给lp那就是u愿意给lp
map[u][lp]=1;
}
for(int ji=1;ji<=n;ji++){
for(int jl=1;jl<=n;jl++)
if(map[ji][jl]==1)
fa[jl]=fa[ji];//既然愿意那就认祖
}
work();//最后检查有多少的老祖
printf("%d",ans);
return 0;
}
用map[210][210] 这个很妙建议反复观看,最好拿出小笔去写一写一下看看到底是为啥子
ok来道oj
题目描述
话说我们家小谭啊,他特别的好吃懒做,对于吃还很挑剔,有一天他得到了一堆的饮料,他就想要喝掉这些饮料,但是他喝饮料有个特殊的习惯,那就是不喜欢连续两次喝相同的饮料,小谭不知道是否存在一种喝饮料的顺序使得他能够喝完所有的饮料,所以他请你帮他写个程序来测一测。
输入
多组输入
每组第一行输入一个n ( 0 < n <= 10 ) 代表饮料的种类数量,接下来的一行有n个数,代表每种饮料的数量 p(p < 1e9 )
输出
如果存在一种喝饮料的顺序能够使小谭喝完所有的饮料就输出 yes 否则输出 no 。
样例输入 复制
3
4 1 1
5
5 4 3 2 1
样例输出 复制
这个思路就是你有木有看明白咋去写,其实很简单的啦,你只要找到最大的饮料数量与剩下的去比较就可以了,只要剩下的大于等于max-1就可以了,至于为啥子,你就想一想插孔以及路边的树就ok了,思路就是这么个思路。上码!
#include<stdio.h>
int main(){
long long n,c[20];
while(scanf("%lld",&n)!=EOF){
for(long long h=0;h<n;h++){
scanf("%lld",&c[h]);
}
long long sun=0,max=-1;
for(long long y=0;y<n;y++)
if(c[y]>max)
max=c[y];
for(long long j=0;j<n;j++)
sun+=c[j];
if((sun-max)>=max-1)
printf("yes\n");
else
printf("no\n");
}
return 0;
}
代码简单的不行就不多逼逼,ok今天星期5歇逼才是主流,我不干了!liu,rua,rua,rua!