排座位(天梯赛初赛)

布置宴席最微妙的事情,就是给前来参宴的各位宾客安排座位。无论如何,总不能把两个死对头排到同一张宴会桌旁!这个艰巨任务现在就交给你,对任何一对客人,请编写程序告诉主人他们是否能被安排同席。

输入格式:

输入第一行给出3个正整数:N\le100),即前来参宴的宾客总人数,则这些人从1到N编号;M为已知两两宾客之间的关系数;K为查询的条数。随后M行,每行给出一对宾客之间的关系,格式为:宾客1 宾客2 关系,其中关系为1表示是朋友,-1表示是死对头。注意两个人不可能既是朋友又是敌人。最后K行,每行给出一对需要查询的宾客编号。

这里假设朋友的朋友也是朋友。但敌人的敌人并不一定就是朋友,朋友的敌人也不一定是敌人。只有单纯直接的敌对关系才是绝对不能同席的。

输出格式:

对每个查询输出一行结果:如果两位宾客之间是朋友,且没有敌对关系,则输出No problem;如果他们之间并不是朋友,但也不敌对,则输出OK;如果他们之间有敌对,然而也有共同的朋友,则输出OK but...;如果他们之间只有敌对关系,则输出No way

输入样例:

7 8 4
5 6 1
2 7 -1
1 3 1
3 4 1
6 7 -1
1 2 1
1 4 1
2 3 -1
3 4
5 7
2 3
7 2

输出样例:

No problem
OK
OK but...
No way

这题我第一次用的是二维数组。满分25,得了19分,怎么改都改不对,仔细的把图画画发现很多情况不能实现。主要朋友的朋友不好弄,很麻烦。查了查“并查集”,这题就变得很容易了。

直接说说并查集的思路吧。如图,


1和2是朋友,2和3是朋友。1和3之间就连通了,题目说朋友的朋友也是朋友,所以1和3也是朋友。我们用数组a[]表示下标对应的下一个点多少。例如图  a[1]=2,a[2]=3,     每个点都有自己的下一个点。当下一个点没有了,找不到了,他就是最后一个点,所有的点只要能找到最后这个点的都是朋友

例如现在加进来一个5,5和3是朋友。a[5]=3,虽然a[1]=2,一直找到尽头:a[1]=a[2]=3;所以5和1也是朋友


int find(int x){//寻找一个点的最后一个节点
int r=x;
while(1){
if(a[r]==0){
return r;
}
r=a[r];//没到最后一个,就往下一个寻找
}
}

当然有个合并的函数,用来对自己的下一个点赋值

void add(int n,int m){
int x=find(n);//分别找到两个点的最终的结点
int y=find(m);
if(x!=y)
 a[x]=y;

如图

4和6建立的朋友关系,如果5和6也是朋友关系,那么find(5),find(6),发现find(5)=3,find(6)=4,那么3和4建立了朋友关系,即a[3]=3或者a[4]=3

整张图也就都是朋友,连通了


因为题意说了,敌人的敌人并不一定就是朋友,朋友的敌人也不一定是敌人,所以敌人简单的用个二维数组就好

主要思路也就这样,没接触并查集根本不知道这个思路,刷题真重要。从中学到新方法,新思路,巩固自己以前的知识。加油!

#include 
#include 
#include
#include
#include
using namespace std;
int a[200]={0};
int fz[200][200]={0};
int find(int x){
	int r=x;
	while(1){
		if(a[r]==0){
			return r;
		}
		r=a[r];
	}
//	return r;
}
void add(int n,int m){
	int x=find(n);
	int y=find(m);
	if(x!=y)
	  a[x]=y;
} 
int main(){
	int n,m,k;
	cin>>n>>m>>k;
	for(int i=0;i>q>>w>>e;
		if(e==1){
			add(q,w);
		}
		else{
			fz[q][w]=1;
			fz[w][q]=1;
		}
	}
	for(int i=0;i>q>>w;
		if(find(q)==find(w)&&fz[q][w]!=1){
			printf("No problem\n");
		}
		else if(find(q)==find(w)&&fz[q][w]==1){
			printf("OK but...\n");
		}
		else if(find(q)!=find(w)&&fz[q][w]==0){
			printf("OK\n");
		}
		else if(fz[q][w]==1&&find(q)!=find(w)){
			printf("No way\n");
		}
	}
	return 0;
}




你可能感兴趣的:(并查集)