L2-010 row of seats (C language and search collection)

topic

The most subtle thing about setting up a banquet is to arrange seats for all the guests who come to the banquet. In any case, it is impossible to line up two rivals at the same banquet table! This difficult task is now entrusted to you. For any pair of guests, please write a program to tell the host whether they can be arranged to sit together.

Input format:
Enter the first line to give 3 positive integers: N (≤100), that is, the total number of guests who came to the banquet, then these people are numbered from 1 to N; M is the known relationship between the two guests Number; K is the number of queries. Then M lines, each line gives the relationship between a pair of guests, the format is: guest 1 guest 2 relationship, where the relationship is 1 means friend, -1 means dead opponent. Note that two people cannot be both friends and enemies. In the last K lines, each line gives a pair of guest numbers to be queried.

It is assumed here that friends of friends are also friends. But the enemy of the enemy is not necessarily a friend, and the enemy of a friend is not necessarily an enemy. Only a purely direct hostile relationship is absolutely impossible to sit together.

Output format:
output one line of result for each query: if two guests are friends and there is no hostile relationship, then output No problem; if they are not friends but not hostile, then output OK; if they are not If there is hostility between them, but there are also friends in common, then output OK but...; if they only have hostile relationship, output No way.

Input sample:

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

Sample output:

No problem
OK
OK but...
No way

Analysis of thinking: Friends of friends are friends, but the relationship between the enemy’s enemy and the friend’s enemy is uncertain, so you can use a one-dimensional array **fir[]** to adopt and store the relationship between friends. A two-dimensional array = flat stores the relationship of the enemy separately

For example, the relationship information given in the title is abstracted into a graph

to connect the points that are friends. If the two points can be reached, it means that the two people are friends. For example, 1 , 4 , 2 , 3 are friends, like 1, 6 is not a friend

Now let’s simulate the process of searching and merging. The
lowest value is the value corresponding to the current array fir subscript.

5 6 1
2 7 -1
1 3 1
3 4 1
6 7 -1
1 2 1
1 4 1
2 3 -1
index 1 2 3 4 5 6 7
initialization 1 2 3 4 5 6 7
Enter 5, 6 1 2 3 4 5 6->5 7
1,3 1 2 3->1 4 5 5 7
3,4 1 2 1 4->1 5 5 7
1,2 1 2->1 1 1 5 5 7
1,4 1 1 1 1 5 5 7
Final relationship 1 1 1 1 5 5 7

The first group of friends is 1 , 3, that is to say, 1 can be regarded as the leader of a group of friends. The leader of each person is the same, so
the relationship of 1, 2, 3, 4 is all friends. Friends, 5, 6 are friends

Insert picture description here

index 1 2 3 4 5
initialization 1 2 3 4 5
Enter 3,1 1->3 2 3 4 5
3,2 3 2->3 3 4 5
4,5 3 3 3 4 5->4
1,5 3 3 3 4->3 4
Final relationship 3 3 3 3 4

Here a first group of friends 3,1 , 3 as the head, to 1,5 , when a value is to get 3 , 5 to get the value is 4 , 4! = 5 , we must continue to 4 to get to 4 to get the value is 4, and the two do not get the same value, we need to re-establish relations head, FIR [4] = 3
last their heads are 3, The same explanation can be a friend
compression path: for example, find find (5), 5 to 4, continue 4 to get 3, and 3 to get 3, then assign 5 to 3, then find again next time When find (5), you can directly get 3 from 5, reduce the number of calls
, and judge whether it is a friend or an enemy in the final output.

AC code:

#include <stdio.h>
#include <stdlib.h>

int fir[105]={
    
    0};//用做合并是否是朋友
int flat[105][105]={
    
    0};//标记是否是敌人 1为敌人
int find(int x){
    
     //用做查找对应头朋友的编号 
	if(fir[x]==x)
		return x;
	else
		return fir[x]=find(fir[x]); //压缩路径
}
int merge(int a,int b){
    
     //合并新的朋友关系 
	int b1 = find(a); //获取a对应的头朋友 
	int b2 = find(b);  
	if(b1!=b2) //不相等,说明两个还没有确立朋友关系 
		fir[b2] = b1;
} 
int main(int argc, char *argv[]) {
    
    
	int n,m,k,i,j;
	int a,b,c;
	scanf("%d%d%d",&n,&m,&k);
	for(i=1;i<=n;i++){
    
    
		fir[i] = i; //标上编号 
	} 
	for(i=0;i<m;i++){
    
    
		scanf("%d%d%d",&a,&b,&c);
		if(c==1){
    
     //朋友 
			merge(a,b);
		}else{
    
    
			flat[a][b] = 1;
			flat[b][a] = 1;
		}
	}
	int b1,b2;
	for(i=0;i<k;i++){
    
    
		scanf("%d%d",&a,&b);
		b1 = find(a);
		b2 = find(b);
		if(b1==b2&&flat[a][b]==0){
    
    //朋友 
			printf("No problem\n");
		}else if(b1!=b2&&flat[a][b]==0){
    
    //不是朋友和敌人 
			printf("OK\n");
		}else if(b1==b2&&flat[a][b]==1){
    
    //朋友和敌人 
			printf("OK but...\n");
		}else{
    
    
			printf("No way\n");
		}
	}
	return 0;
}

Guess you like

Origin blog.csdn.net/qq_45880043/article/details/108913233