F - Firetrucks Are Red Kattis - firetrucksarered(并查集加路径压缩)

Lily is fascinated by numbers. She believes the whole world revolves around them, and that everything is connected by numbers. Her friends, Alice, Bob, Charlie and Diane, are not convinced. But she gives them an example:
Alice lives in house number 25 on her street, but that is exactly Bob’s age. Bob is born on June 4th, and Charlie was his parents’ fourth child. Finally, Diane has five fingers on her left hand, which happens to be the same as the number of toes that Bob has on his right foot!
This shows that her friends are all connected—either directly or indirectly—by numbers. But she still has to convince her family as well as her coworkers.

Given a group of n individuals, and a set of numbers that describe each individual, help Lily come up with a proof that shows that everyone in this group is either directly or indirectly connected by numbers, or determine that this is not possible.

Input
The input consists of:

One line with an integer n (2≤n≤2⋅105), the number of individuals in the group. The individuals are numbered from 1 to n.

n lines, describing the individuals in the group.

The ith such line starts with an integer mi (1≤mi≤2⋅105), the number of numbers that describe individual i.

The remainder of the line has mi distinct integers di,1,…,di,mi (1≤di,j≤109 for each j), the set of numbers that describe individual i.

It is guaranteed that the sum over all mi is at most 2⋅105.

Output
Output a proof in the form of n−1 lines, each of which contains three integers p, q and r, where p and q are distinct individuals that are both described by the number r. Using only these relations, it must be possible to show that any pair of individuals in the group are connected either directly or indirectly.

If no such proof exists, output “impossible”. If there are multiple proofs, you may output any one of them.
在这里插入图片描述
思路:并查集加路径压缩
代码:

#include <algorithm>
#include <stdio.h>
#include <cstring>
#include <deque>
#include <list>
#include <map>
#include <iostream>
#include <istream>
#include <queue>
#include <stack>
#include <vector>
using namespace std;
#define INF 0x3f3f3f3f
#define Max 1000001
map<int,int>vis;
int parent[200001];
int n;
int book1[200001];
int book2[200001];
int book3[200001];
int ans=0;
void init()
{
    for(int i=1;i<=n;i++)
    {
        parent[i]=i;
    }
}
int Find(int x)
{
    if(parent[x]!=x)
        parent[x]=Find(parent[x]);
    return parent[x];
}

void Merge(int x,int y,int key)
{
    if(Find(x)!=Find(y))
    {
        parent[Find(y)]=Find(x);
        book1[ans]=x;
        book2[ans]=y;
        book3[ans++]=key;
    }
    return;
}
int main()
{
    cin>>n;
    init();
    for(int i=1;i<=n;i++)
    {
        int m;
        cin>>m;
        for(int j=0;j<m;j++)
        {
            int key;
            cin>>key;
            if(vis[key]==0)
            {
                vis[key]=i;
            }
            else
            {
                Merge(vis[key],i,key);
                vis[key]=i;
            }
        }
    }
    if(ans==n-1)
    {
        for(int i=0;i<ans;i++)
            cout<<book1[i]<<" "<<book2[i]<<" "<<book3[i]<<endl;
    }
    else
    {
        cout<<"impossible"<<endl;
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值