题意:
比较难理解,直到我看题解之前,都没能得出明确的题意。
总结题意后得到: 给出m个集合,每个集合中的元素必须挨着,因为原题说 首先要保证结构清晰,也就是说集合之间不能有交叉的连线;
思路:
虽然我没能弄清具体的题意,但是也想到了从最下面对集合进行并查集操作,每个集合保证字典序最小即可,
从下往上实现并查集操作可以达到结构清晰的目的,不会出现相交的情况,(其实也会有某个元素同时在多个集合中的情况)
本题解系参考 vj 代码;
注释部分为之前自己写的代码(错误)待修改==;
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 7;
struct node {
int h;
vector<int> vec;
bool operator < (const node &t) const {
return (h > t.h);
}
}a[maxn];
int n, m, q;
int f[maxn], last[maxn], pre[maxn];
vector<int> ans;
int find_(int i) {
return f[i] == i ? f[i] : (f[i] = find_(f[i]));
}
void init() {
scanf("%d %d %d", &n, &m, &q);
for(int i = 0; i < m; ++i) {
scanf("%d", &a[i].h);
int k; scanf("%d", &k);
a[i].vec.resize(k);
for(int j = 0; j < k; ++j)
scanf("%d", &a[i].vec[j]);
}
// cout << " 2333 " << endl;
for(int i = 1; i <= n; ++i) {
a[m].vec.push_back(i);
f[i] = i; last[i] = i; pre[i] = -1;
}
++m;
sort(a, a+m);
}
void solve() {
for(int i = 0; i < m; ++i) {
for(int j = 0; j < a[i].vec.size(); ++j)
a[i].vec[j] = find_(a[i].vec[j]);
sort(a[i].vec.begin(), a[i].vec.end());
int ff = a[i].vec[0];
for(int j = 1; j < a[i].vec.size(); ++j) {
if(find_(a[i].vec[j]) == ff) continue;
int p = last[ff];
pre[p] = a[i].vec[j];
last[ff] = last[a[i].vec[j]];
f[a[i].vec[j]] = ff;
}
}
int p = find_(1);
while(p != -1) {
ans.push_back(p);
p = pre[p];
}
for(int i = 0; i < q; ++i) {
int d; scanf("%d", &d);
printf("%d\n", ans[d-1]);
}
}
int main() {
init();
solve();
return 0;
}
// ———————————— 分割线 ————————————
//#include<iostream>
//#include<algorithm>
//#include<cstdio>
//#include<cstdlib>
//#include<cstring>
//#include<string>
//#include<cmath>
//#include<set>
//#include<queue>
//#include<stack>
//#include<map>
//#define PI acos(-1.0)
//#define in freopen("in.txt", "r", stdin)
//#define out freopen("out.txt", "w", stdout)
//#define kuaidian ios::sync_with_stdio(0);
//
//using namespace std;
//typedef long long ll;
//typedef unsigned long long ull;
//const int maxn = 1e5 + 7, maxd = 670000 + 7;
//const ll mod = 1e9 + 7;
//const int INF = 0x7f7f7f7f;
//
//int n, m, q, cnt;
map<int, vector<int> > mp;
//int f[maxn], last[maxn], pre[maxn];
//vector<int> ret;
set<int> st;
bool vis[maxn];
//
//struct node {
// int h;
// vector<int> vec;
//} a[maxn];
//bool cmp(node a, node b) {
// return ( (a.h > b.h) || (a.h == b.h && a.vec[0] < b.vec[0]) );
//}
//
//int find_(int i) {
// return f[i] == i ? (i) : (f[i] = find_(f[i]));
//}
//
//
//
//void solve(int x) {
// if(vis[x]) return;
// if(mp[x].size()) {
// ans[cnt++] = x; //st.insert(x);
// vis[x] = 1;
// for(int i = 0; i < mp[x].size(); ++i)
// if(vis[mp[x][i]] == 0) {
// solve(mp[x][i]);
// }
//
// }
//}
//
//int main() {
//
// while( ~scanf("%d %d %d", &n, &m, &q) && n ) {
// st.clear();
// memset(vis, 0, sizeof vis);
//
// for(int i = 0; i < m; ++i) {
// scanf("%d", &a[i].h);
// int l_;
// scanf("%d", &l_);
// for(int i = 0; i < l_; ++i) {
// int x;
// scanf("%d", &x);
// a[i].vec.push_back(x);
// }
// sort(a[i].vec.begin(), a[i].vec.end());
// }
// sort(a, a+m, cmp);
// for(int i = 1; i <= n; ++i) f[i] = i;
//
// for(int i = 0; i < m; ++i) {
// int t = a[i].vec[0];
// for(int j = 1; j < a[i].vec.size(); ++j) {
// union_(t, a[i].vec[j]);
// mp[t].push_back(a[i].vec[j]);
// }
// }
//
// cnt = 1;
// m--;
// for(int i = 0; i < a[m].vec.size(); ++i ) {
// solve(a[m].vec[i]);
if(st.count() == 0) {
}
ans[cnt++] = a[m].vec[i];
for(int j = 0; j < mp[a[m].vec[i]].size(); ++j) {
ans[cnt++] = mp[a[m].vec[i]][j];
}
// }
//
// for(int i = 0; i < q; ++i) {
// int x;
// scanf("%d", &x);
// printf("%d\n", ans[x]);
// }
//
// }
// return 0;
//}
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//