• 数据结构作业——直通车(并查集)


    直通车

    Description

    作为一个老司机,开车前最让金金犯难的事就是给乘客们安排座位了,总不 能把俩死对头安排到一起吧!金金决定把这可怕的任务交给你,对任意一对乘客, 请你判断他俩的关系。

    Input

    输入第一行为三个整数 N, M, K( N 为乘客的数目, 乘客的编号为 1 到 N; M 为已知两两乘客之间的关系数; K 为查询的条数)。 1<=N,M,K<=100。

    随后 M 行,每行给出一对乘客之间的关系, 格式为:“ 乘客 1 乘客 2 关系” , 其中“ 关系” 为 1 表示是朋友,为-1 表示是敌人。注意两人不可能既是直接的 朋友又是直接的敌人。

    最后 K 行,每行给出一对需要查询的宾客编号。 规定: 朋友的朋友也是朋友(所以两个人可能直接关系上是敌人但间接关系 上是朋友)。但敌人的敌人并不一定就是朋友,朋友的敌人也不一定是敌人。 也 就是说只有朋友的关系能传递,而敌人的关系则不能。

    Output

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

    Sample Input

    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

    Good job
    No problem
    OK but...
    No way

    思路

    如果两者之间的关系是朋友,则将他们合并起来,如果两者是敌人,则建立邻接表存取每个人的敌人是谁,在判断二者关系的时候,如果两人是朋友,则在他们各自的邻接表查找有没有对方出现,有的话说明既是朋友,又是敌人。

     AC代码
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int maxn = 105;
    int tot = 0,fa[maxn],head[maxn];
    struct Edge{
    	int to,next;
    }edge[maxn<<1];
    
    int find(int x)
    {
    	int r = x;
    	while (r != fa[r])	r = fa[r];
    	int i = x,j;
    	while (i != r)
    	{
    		j = fa[i];
    		fa[i] = r;
    		i = j;
    	}
    	return r;
    } 
    
    void unite(int x,int y)
    {
    	int fx = find(x),fy = find(y);
    	if (fx == fy)	return;
    	fa[fx] = fy;
    }
    
    void addedge(int u,int v)
    {
    	edge[tot].to = v,edge[tot].next = head[u];
    	head[u] = tot++;
    }
    
    int main()
    {
    	//freopen("input.txt","r",stdin);
    	int N,M,K,x,y,opt,i;
    	bool flag;
    	scanf("%d%d%d",&N,&M,&K);
    	for (i = 0;i <= N;i++)	fa[i] = i,head[i] = -1;
    	while (M--)
    	{
    		scanf("%d%d%d",&x,&y,&opt);
    		if (opt == 1)	unite(x,y);
    		else
    		{
    			addedge(x,y);
    			addedge(y,x);
    		}
    	}
    	while (K--)
    	{
    		scanf("%d%d",&x,&y);
    		if (find(x) == find(y))
    		{
    			flag = true;
    			for (i = head[x];i != -1;i = edge[i].next)
    			{
    				if (edge[i].to == y)	flag = false;
    			}
    			if (flag)	printf("Good job
    ");
    			else	printf("OK but...
    ");
    		}
    		else
    		{
    			flag = true;
    			for (i = head[x];i != -1;i = edge[i].next)
    			{
    				if (edge[i].to == y)	flag = false;
    			}
    			if (flag)	printf("No problem
    ");
    			else	printf("No way
    ");
    		}
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    回顾:异常处理,值传递和引用传递
    回顾:静态变量和实例变量、构造器
    多态、抽象类与接口
    回顾:面向对象、基本类型
    总结一下《深入理解Java虚拟机》
    百度实习生面试题
    面试题
    阿里面试
    Shell
    Collector详解
  • 原文地址:https://www.cnblogs.com/ZhaoxiCheung/p/6063771.html
Copyright © 2020-2023  润新知