[swustoj 1091] 土豪我们做朋友吧
土豪我们做朋友吧(1091)
问题描述:
人都有缺钱的时候,缺钱的时候要是有个朋友肯帮助你,那将是一件非常幸福的事情。有N个人(编号为1到N),一开始他们互相都不认识,后来发生了M件事情,事情分为2个种类,1:A和B成为了朋友,并且A的所有朋友都成了B的朋友,B的所有朋友也都成了A的朋友。2:A缺钱了,请求帮助,他需要向他朋友中钱最多的请求帮助,若不止一位,选择编号最小的。
输入:
多组测试数据,每组第一行是整数N(2<=N<=100000),表示有N个人,第二行N个数据,依次表示每个人有多少钱,第三行是M(1<=M<=100000),表示发生了M个事件。接下来是M行,首先输入事件种类P(1或者2),然后是对应的两个或者一个整数A,B或者A。数据保证都在32位以内。
输出:
对于每一个事件2,输出A需要请求的人的编号,若没有人能够帮助他,输出"NO ONE CAN HELP!"。
样例输入
3
1 2 3
3
2 1
1 1 3
2 1
样例输出
NO ONE CAN HELP!
3
并查集、维护最大和次大就是了
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> using namespace std; #define INF 0x3f3f3f3f #define N 100010 int n,m; int a[N]; int f[N]; pair<int,int> mx[N]; //最大的值、人 pair<int,int> cx[N]; //次大的值、人 pair<int,int> tmp[5]; bool cmp(pair<int,int> a,pair<int,int> b) { if(a.first!=b.first) return a.first>b.first; return a.second<b.second; } void init() { for(int i=1;i<=n;i++) { f[i]=i; scanf("%d",&mx[i].first); mx[i].second=i; cx[i].first=-1; cx[i].second=-1; } } int Find(int x) { if(x!=f[x]) f[x]=Find(f[x]); return f[x]; } void UN(int x,int y) { x=Find(x); y=Find(y); if(x==y) return; f[x]=y; tmp[0]=mx[x];tmp[1]=cx[x]; tmp[2]=mx[y];tmp[3]=cx[y]; sort(tmp,tmp+4,cmp); mx[x]=mx[y]=tmp[0]; cx[x]=cx[y]=tmp[1]; } int main() { while(scanf("%d",&n)!=EOF) { init(); scanf("%d",&m); while(m--) { int op,a,b; scanf("%d%d",&op,&a); if(op==1) { scanf("%d",&b); UN(a,b); } else { b=Find(a); if(mx[b].first!=-1 && mx[b].second!=a) printf("%d\r\n",mx[b].second); else if(cx[b].first!=-1) printf("%d\r\n",cx[b].second); else printf("NO ONE CAN HELP!\r\n"); } } } return 0; }
趁着还有梦想、将AC进行到底~~~by 452181625