列表

详情


NC204870. 人人都是好朋友

描述

牛可乐作为三军统帅,是要时时刻刻关照着下属的。

现在牛可乐想要知道自己的手下之间的友好关系,所以他收集了  张纸条,上面写着三个整数 ,表示如果 ,表示手下  和手下  是朋友,反之则是敌人。

牛可乐想要知道这些信息有没有互相矛盾的地方,可是这个问题太难了,只好来问你了

如果 A 与 B 友好,又与 友好,那么 与 也是友好的。

如果两个人既是友好的又是不友好的则视为相互矛盾的。
牛可乐的手下有 1e9 个。

输入描述

输入第一行给出一个正整数 ,表示测试案例的数量。

对于每个测试用例.第一行给出一个正整数 ,表示有  个友好关系

接下来每  行给出三个正整数 ,表示手下  和手下  之间的友好关系.

输出描述

每组案例输出一行,若这些关系没有矛盾,输出  "YES”,否则输出 “NO”

示例1

输入:

2
3
1 2 1
1 3 1
2 3 1
3
1 2 1
1 3 1
2 3 0

输出:

YES
NO

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 1677ms, 内存消耗: 101280K, 提交时间: 2020-05-13 11:19:32

#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
ll n,m;
unordered_map<int,int>fazz;//初始化都为零 
int find(int v)
{
    if(fazz[v] == 0)
        return v;
    else
    {
        fazz[v]=find(fazz[v]);
        return fazz[v];
    }
}
/*void union(int x,int y)
{
	int m=find(x);
	int n=find(y);
	fazz[m]=n;
	return ;
}*/
int main()
{
	cin>>n;
	while(n--)
	{
		cin>>m;
		int flag=1;
		while(m--)
		{
			int a,b,c;
			scanf("%d%d%d",&a,&b,&c);
			if(flag==0)continue;
			int x,y;
			x=find(a),y=find(b); 
			if(c==1)
			{
				if(x!=y&&x!=a&&y!=b)flag=0;
				else fazz[x]=y;
			}
			else if(c==0)
			{
				if(x==y)flag=0;
			}
		}
		if(flag==0)printf("NO\n");
		else printf("YES\n");
		fazz.clear();
	}
	return 0;
}

C++(g++ 7.5.0) 解法, 执行用时: 1934ms, 内存消耗: 144392K, 提交时间: 2023-05-13 20:24:35

#include<bits/stdc++.h>
using namespace std;
int t,n;		
unordered_map<int,int>p;
int find(int x){
	if(x!=p[x]) p[x]=find(p[x]);
	return p[x];
}
int main(){
	cin>>t;
	while(t--){
		p.clear();
		unordered_map<int,int>mp;
		scanf("%d",&n);
		int f=0;
		for(int i=0;i<n;i++){
			int a,b,c;
			scanf("%d%d%d",&a,&b,&c);
            if(f==1) continue;
            if(!p.count(a)) p[a]=a;
            if(!p.count(b)) p[b]=b;
			if(a>b) swap(a,b);
			if(c==1){
				if(mp[a]==b){
					f=1;
				}else p[find(a)]=p[find(b)];
			}else{
				if(p[find(a)]==p[find(b)]){
					f=1;
				}else mp[a]=b;
			}
		}if(f==1){
			printf("NO\n");
		}else{
			printf("YES\n");
		}
	}
	return 0;
}

pypy3 解法, 执行用时: 3094ms, 内存消耗: 175364K, 提交时间: 2023-04-02 16:53:45

def merge(x: int):
    global mp
    if mp.__contains__(x) == False:
        mp[x] = x
        return x
    while x != mp[x]:
        x, mp[x] = mp[x], mp[mp[x]]
    return x


mp = dict()
t = int(input())
for i in range(t):
    n, flag = int(input()), False
    for j in range(n):
        a, b, c = map(int, input().split())
        if flag == True:
            continue
        x, y = merge(a), merge(b)
        if c == False:
            flag = (x == y)
        elif x < y:
            mp[b] = x
        elif x > y:
            mp[a] = y
    if flag == True:
        print("NO")
    else:
        print("YES")

C++ 解法, 执行用时: 1201ms, 内存消耗: 81620K, 提交时间: 2021-06-17 20:25:46

#include <iostream>
#include <cstdio>
#include <unordered_map>
using namespace std;
unordered_map<int,int> f;
int find(int v){
	return f[v]==0?v:find(f[v]);
}
void merge(int u,int v){
	int t1=find(u),t2=find(v);
	f[t1]=t2;
}
int main(){
	int T,n,a,b,c;
	scanf("%d",&T);
	while(T--){
		bool flag=true;
		scanf("%d",&n);
		while(n--){
			scanf("%d%d%d",&a,&b,&c);
			if(!flag) continue;
			int x=find(a),y=find(b);
			if(c==1){
				if(x!=a&&y!=b&&x!=y) flag=false;
				else f[x]=y;
			}
			else if(x==y) flag=false;
		}
		printf("%s\n",flag?"YES":"NO");
		f.clear();
	}
	return 0;
}

上一题