FZU 2192 位置信息挖掘 (种类并查集)

题目链接click here~~

题目大意】:

O2O即Online To Offline,是指将线下的商务机会与互联网结合,让互联网成为线下交易的前台。这些商务机会主要是偏服务类的商品,例如汽车售后服务、摄影服务、餐饮、电影等,其特色是线上购买、线下服务。

因此,对这类垂直行业的商品做移动推荐时,用户和商品的位置信息显得格外重要。但是,可能存在用户、商品的位置信息缺失的情况,例如:用户不共享位置信息、商家未填写位置信息……

现在,Jason给出用户在移动端的购买行为数据,以及商品集合,希望能补全一些缺失的位置信息。为了简化问题,假设:

1、由于是服务类的商品,如果用户位于城市A,那么该用户只会购买位于城市A的商品。

2、数据不存在噪声,即测试数据都是合法的。

Input

包含多组数据

每组输入数据格式如下:

第一行,三个数:N、M、Q,表示N个商品,M条购买行为数据,Q个询问。

接下来N行,每行两个数:itemId、cityId,表示商家填写的服务itemId,位于城市cityId。

接下来M行,每行三个数:userId、itemId、cityId,表示用户userId购买了服务itemId,移动端定位城市cityId。

接下来Q行,每行两个数:0、itemId或者1、userId,表示询问服务itemId所在的城市,或者用户userId所在的城市。

注意:0表示位置信息缺失。

Output

每组输出数据格式如下: Q行,每行一个数:cityId,表示服务itemId位于cityId,或者用户userId位于cityId。

Sample Input

3 2 5

2 0

3 0

1 3

2 2 2

1 1 0

0 1

0 2

0 3

1 1

1 2

Sample Output

3

2

0

3

2

解题思路】:用到了并查集,开始直接用模拟去做,发现不能简单的去处理,所谓种类并查集,只是一个区别罢了,涉及到不同的种类对象,把需要处理的itemid和cityid用并查集合并起来,因为题目中确定两者一一对应的关系,然后我们去合并的时候注意要及时更新num[fy]=num[fx],具体看代码吧~~

代码:

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
const int N=1e5+10;
int fa[N];
int num[N];
int treeh[N];
int n,m,q,za,zb;
int itemid,cityid,usedid;
void init()
{
    for(int i=0; i<=n+m; ++i)
    {
        fa[i]=i;
        treeh[i]=num[i]=0;
    }
}
int find(int x)
{
    if(x==fa[x]) return x;
    else return fa[x]=find(fa[x]);
}
void unite(int x,int y,int d)//每次合并的时候更新num
{
   int fx=find(x);
   int fy=find(y);
   if(d) num[fx]=d;//注意更新
   fa[fx]=fy;
   if(num[fy]==0) num[fy]=num[fx];
}
int main()
{
    while(cin>>n>>m>>q)
    {
        init();
        for(int i=0; i<n; ++i)
        {
            cin>>itemid>>cityid;
            if(cityid) num[itemid]=cityid;
        }
        for(int i=0; i<m; ++i)
        {
            cin>>usedid>>itemid>>cityid;
            if(cityid) num[usedid+n]=cityid;
            unite(usedid+n,itemid,cityid);
        }
        while(q--)
        {
            cin>>za>>zb;
            if(za==0) cout<<num[find(zb)]<<endl;
            else cout<<num[find(zb+n)]<<endl;
        }
    }
    return 0;
}
/*
3 2 5
2 0
3 0
1 3
2 2 2
1 1 0
0 1
0 2
0 3
1 1
1 2
Sample Output
3
2
0
3
2
*/
时间: 2024-10-28 21:31:46

FZU 2192 位置信息挖掘 (种类并查集)的相关文章

种类并查集

//http://acm.timus.ru/problem.aspx?space=1&num=1003//分析:树和递归最常用的思想是分治:并查集是一种合并树的数据结构:合并树或加入树节点时,我们只在意新建立的树边上相邻的两个树节点之间的关系,实际上树边只在意相邻两个树节点之间的关系//思路:可以讲一段连续区间的奇偶性表示成两个前缀和的奇偶性:将出现的离散的点用map离散化一下:将数量减少的点做一次种类并查集 1 #include"iostream" 2 #include&qu

A Bug&#39;s Life(种类并查集)(也是可以用dfs做)

http://acm.hdu.edu.cn/showproblem.php?pid=1829 A Bug's Life Time Limit:5000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Practice HDU 1829 Description Background Professor Hopper is researching the sexual behavior of a r

poj 2492 a bug&#39;s life 简单种类并查集

题意大致为找同性恋的虫子.... 这个比食物链要简单些.思路完全一致,利用取余操作实现关系之间的递推. 个人感觉利用向量,模和投影可能可以实现具有更加复杂关系的并查集. 1 #include<cstdio> 2 using namespace std; 3 const int MAXN=50010; 4 int fa[MAXN]; 5 int rel[MAXN]; // 0代表同类,1代表吃fa[i],2代表被吃 6 void _set(int n) 7 { 8 for(int i=1;i&l

POJ1182 食物链---(经典种类并查集)

题目链接:http://poj.org/problem?id=1182 食物链 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 69207   Accepted: 20462 Description 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物,以1-N编号.每个动物都是A,B,C中的一种,但是我们并不知道它到底是哪一种. 有人用两种说法对这N个动物所构成的食

poj1733(种类并查集+离散化)

题目链接: http://poj.org/problem?id=1733 题意: 输入n表示有一个长度为n的0,1字符串, m表示接下来有m行输入, 接下来的m行输入中x, y, even表示第x到第y个字符中间1的个数为偶数个, x, y, odd表示第x到第y个字符中间1的个数为奇数个, 若m句话中第k+1是第一次与前面的话矛盾, 输出k; 思路: 若x, y之间1的个数为偶数个, 那么1~x 与1~y中1的个数同奇偶性, 反之则异奇偶性, 我们可以将其理解为若输入x, y, even, 即

POJ1703--Find them, Catch them(种类并查集)

Time Limit: 1000MSMemory Limit: 10000K Total Submissions: 32909Accepted: 10158 Description The police office in Tadu City decides to say ends to the chaos, as launch actions to root up the TWO gangs in the city, Gang Dragon and Gang Snake. However, t

poj 1182 食物链(种类并查集 ‘初心者’)

题目链接:http://poj.org/problem?id=1182 借着这题可以好好理解一下种类并查集,这题比较简单但挺经典的. 题意就不解释了,中问题. 关于种类并查集结局方法也是挺多的 1扩增倍数. 就是有几种关系就建立几倍数组,具体方法在这里不详细说了,这种方法有弊端 比较复杂而且内存消耗比较大如果关系比较多就容易爆掉. 2向量的方法. 这种方法要详细解说一下.这个方法好处都有啥.......(自行脑补后面的话) 这个方法的优点占用内存比较小而且比较简洁.只要找到关系就行. 下面就用方

poj1417(种类并查集+dp)

题目:http://poj.org/problem?id=1417 题意:输入三个数m, p, q 分别表示接下来的输入行数,天使数目,恶魔数目: 接下来m行输入形如x, y, ch,ch为yes表示x说y是天使,ch为no表示x说y不是天使(x, y为天使,恶魔的编号,1<=x,y<=p+q):天使只说真话,恶魔只说假话: 如果不能确定所有天使的编号,输出no,若能确定,输出所有天使的编号,并且以end结尾: 注意:可能会有连续两行一样的输入:还有,若x==y,x为天使: 思路:种类并查集+

HDU 3038 How Many Answers Are Wrong(种类并查集)

题目链接 食物链类似的题,主要是在于转化,a-b的和为s,转换为b比a-1大s.然后并查集存 此节点到根的差. 假如x的根为a,y的根为b: b - y = rank[y] a - x = rank[x] y - x = s 可以推出b - a = rank[y] - rank[x] + s; 并查集 延迟更新什么的,都忘了啊. 还有这题,如果是x--的话,记得更新0的根. #include <cstring> #include <cstdio> #include <stri