F - Sorting a Matrix(拓扑&缩点)
行、列可以独立成两个问题。
行要求上一行的mini≤maxi≤mini+1≤maxi+1,i<nmin_i\le max_i \le min_{i+1}\le max_{i+1} ,i <nmini≤maxi≤mini+1≤maxi+1,i<n。
这个预处理一波排序即可,0跳过。
列的话,考虑拓扑关系,每列建立关系,注意某一行值相同得列,可以缩点
比如c1=c2=c3<c4=c5=c6c_1=c_2=c_3<c_4=c_5=c_6c1=c2=c3<c4=c5=c6 那么我们新建一个点c7c_7c7。
c1,c2,c3c_1,c_2,c_3c1,c2,c3 连c7c_7c7,c7c_7c7连c4,c5,c6c_4,c_5,c_6c4,c5,c6。 就不需要每对点都连了。
时间复杂度:O(nm)O(nm)O(nm)
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int h, w;
int a[1000005];
vector<int> G[2000005];
bool used[2000005];
vector<int> topo;
void dfs(int v)
{
used[v] = true;
for(auto u : G[v]) if(!used[u]) dfs(u);
topo.push_back(v);
}
int main(void)
{
cin >> h >> w;
for(int y = 1; y <= h; y++) for(int x = 1; x <= w; x++) cin >> a[(y-1)*w+(x-1)];
vector<pair<int,int>> vec;
for(int y = 1; y <= h; y++){
int l = 1e9, r = -1e9;
for(int x = 1; x <= w; x++){
int v = a[(y-1)*w+(x-1)];
if(v) l = min(l, v), r = max(r, v);
}
if(l <= r) vec.push_back({l, r});
}
sort(vec.begin(), vec.end());
for(int i = 1; i < (int)vec.size(); i++){
if(vec[i-1].second > vec[i].first){
cout << "No"<< endl;
return 0;
}
}
for(int y = 1; y <= h; y++){
vector<pair<int, int>> vec;
for(int x = 1; x <= w; x++) if(a[(y-1)*w+(x-1)]) vec.push_back({a[(y-1)*w+(x-1)], x});
sort(vec.begin(), vec.end());
for(int i = 1; i < (int)vec.size(); i++){
if(vec[i-1].first != vec[i].first){
int v = w + vec[i-1].first;
for(int j = i-1; j >= 0; j--){
if(vec[j].first != vec[i-1].first) break;
G[vec[j].second].push_back(v);
}
for(int j = i; j < (int)vec.size(); j++){
if(vec[j].first != vec[i].first) break;
G[v].push_back(vec[j].second);
}
}
}
}
int n = w + h*w;
for(int i = 1; i <= n; i++) if(!used[i]) dfs(i);
reverse(topo.begin(), topo.end());
for(int i = 1; i <= n; i++) used[i] = false;
for(auto v : topo){
used[v] = true;
for(auto u : G[v]){
if(used[u]){
cout << "No" << endl;
return 0;
}
}
}
cout << "Yes" << endl;
return 0;
}
貌似列问题还可以直接对每列排序,然后特判。
不知道为啥排序得复杂度为啥对得,当两列相同得时,cmp为啥直接返回0.
#include<bits/stdc++.h>
using namespace std;
int n,m,x,ov;
bool cmp(vector<int> &a,vector<int> &b){
bool res=ov;
for(int i=0;i<n;i++){
if(a[i]&&b[i]&&a[i]!=b[i]){
res=1;
if(a[i]>b[i]) return 0;
}
}
return res;
}
int main() {
cin>>n>>m;
vector<vector<int> > cv(m);
vector<pair<int,int>> rg;
for(int i=0;i<n;i++){
int mx=0,mn=10000000;
for(int j=0;j<m;j++){
cin>>x;
cv[j].push_back(x);
if(x) mx=max(mx,x),mn=min(mn,x);
}
if(mx) rg.push_back({mn,mx});
}
sort(rg.begin(),rg.end());
for(int i=1;i<rg.size();i++){
if(rg[i-1].second>rg[i].first) return puts("No"),0;
}
sort(cv.begin(),cv.end(),cmp);
ov=1;
for(int i=0;i<m-1;i++) if(!cmp(cv[i],cv[i + 1])) return puts("No"),0;
puts("Yes");
return 0;
}