F. Chat Screenshots
这里提供一个不用拓扑排序并且容易理解的贪心做法
常年没用过拓扑排序的蒟蒻实在是没想到用拓扑排序,其实如果不使用拓扑排序的话,这个题完全可以是绿的思维难度,首先观察样例,发现对于第一个给出的快照,除了作者之外的所有人的顺序就是定了的,也就是需要作者插入一个地方即可,那么我们可以顺着这个思路来做,对于第一个给出的快照,我们记录作者,并且把后面所有人的顺序记下来,然后进行模拟,只需要记录第一个作者之前的人的位置即可,直接插入到那个人之后就可以了,如果这个人的位置比作者之前的原定的位置还要靠前就不考虑,因为第一步已经定顺序了。
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e6 + 10, mod = 1e9 + 7;
int tot;
void solve(){
int n, k; cin >> n >> k;
int f = 0;
vector<int> p(n + 1);
vector<vector<int>> a(k + 1, vector<int> (n + 1));
for(int i = 1; i <= k; i++){
for(int j = 1; j <= n; j++) cin >> a[i][j];
if(i == 1){
f = a[1][1];
for(int j = 2; j <= n; j++) p[j - 1] = a[i][j];
} else{
int pos = 0;
for(int j = 1; j <= n - 1; j++){
if(a[i][j + 1] == f){
pos = j;
break;
}
}
auto it1 = find(p.begin(), p.end(), f);
if(it1 != p.end()) p.erase(it1);
auto it2 = find(p.begin(), p.end(), a[i][pos]) + 1;
if(pos == 1){
if(it1 == p.end()) p.insert(p.begin() + 1, f);
else p.insert(it1, f);
}
else{
if(it1 != p.end() && it1 > it2) p.insert(it1, f);
else p.insert(it2, f);
}
}
}
auto it = find(p.begin(), p.end(), f);
if(it == p.end()) p.insert(p.begin() + 1, f);
for(int i = 1; i <= k; i++){
vector<int> tmp = p;
tmp.erase(find(tmp.begin(), tmp.end(), a[i][1]));
for(int j = 2; j <= n; j++){
if(tmp[j - 1] != a[i][j]){
cout << "NO" << '\n';
return;
}
}
}
cout << "YES" << '\n';
}
signed main(){
std::ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);int t;cin>>t;while(t--)solve();
}

浙公网安备 33010602011771号