题目:
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 Input3 2 52 03 01 32 2 21 1 00 10 20 31 11 2
Sample Output32032
Hint1<=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;}