C - 位置信息挖掘 FZU - 2192-並查集

題目:


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
Hint

1<=N<=LIMIT

1<=M<=LIMIT

1<=Q<= N+M

1<=itemId<=N

1<=userId<=M

0<=cityId<=N+M,0表示位置信息缺失

對於60%的數據,LIMIT<=10^2;對於100%的數據,LIMIT<=10^5


         思路:多對一的並查集+hash,具體思路見代碼。

         代碼:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<bitset>
#include<cstdlib>
#include<cmath>
#include<set>
#include<list>
#include<deque>
#include<map>
#include<queue>
using namespace std;
typedef long long ll;
const double PI = acos(-1.0);
const double eps = 1e-6;
const int INF = 1000000000;
const int maxn = 444444;
int T,n,m,q;
int a,b,c;
int f[maxn];

void init()
{
    for(int i=0;i<maxn;i++)
        f[i]=i;
}

int Get_f(int v)
{
    if(f[v]==v)
        return v;
    else
        return f[v]=Get_f(f[v]);
}

void Merge(int u,int v)
{
    int uu=Get_f(u);
    int vv=Get_f(v);
    //這裏要swap的原因是因爲要保證使得f[小的]=大的,因爲當用戶與服務合併時如果一方沒有對應的城市那麼
    //沒有對應的城市的那一方的f值等於自己的編號必定小與有城市一方的f值
    //於是更新f值小的一方
    if(vv<uu)
        swap(vv,uu);
    if(uu!=vv)
        f[uu]=vv;
}

int main()
{
    while(scanf("%d%d%d",&n,&m,&q)!=EOF)
    {
        init();
        //由於這裏並查集f[i]=j表示用戶i或者服務i對應的城市爲j,但是本題用戶服務和城市編號都會重複,於是
        //要hash映射一下
        //城市編號加上n+m保證比用戶和服務的編號都大
        //用戶編號加上n,服務編號不變
        for(int i=0;i<n;i++)
        {
            scanf("%d%d",&a,&b);
            if(b!=0)
                Merge(a,b+n+m);
        }
        for(int j=0;j<m;j++)
        {
            scanf("%d%d%d",&a,&b,&c);
            Merge(a+n,b);
            if(c!=0)
                Merge(b,c+n+m);
        }
        for(int i=0;i<q;i++)
        {
            scanf("%d%d",&a,&b);
            if(a==1)
                b+=n;
            if(Get_f(b)>=n+m)
                printf("%d\n",Get_f(b)-n-m);
            else
                printf("%d\n",0);
        }
    }
    return 0;
}


發佈了90 篇原創文章 · 獲贊 3 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章