F - Sorting a Matrix(拓扑&缩点)

Posted Harris-H

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了F - Sorting a Matrix(拓扑&缩点)相关的知识,希望对你有一定的参考价值。

F - Sorting a Matrix(拓扑&缩点)

行、列可以独立成两个问题。

行要求上一行的 m i n i ≤ m a x i ≤ m i n i + 1 ≤ m a x i + 1 , i < n min_i\\le max_i \\le min_i+1\\le max_i+1 ,i <n minimaximini+1maxi+1,i<n

这个预处理一波排序即可,0跳过。

列的话,考虑拓扑关系,每列建立关系,注意某一行值相同得列,可以缩点

比如 c 1 = c 2 = c 3 < c 4 = c 5 = c 6 c_1=c_2=c_3<c_4=c_5=c_6 c1=c2=c3<c4=c5=c6 那么我们新建一个点 c 7 c_7 c7

c 1 , c 2 , c 3 c_1,c_2,c_3 c1,c2,c3 c 7 c_7 c7 c 7 c_7 c7 c 4 , c 5 , c 6 c_4,c_5,c_6 c4,c5,c6。 就不需要每对点都连了。

时间复杂度: O ( n m ) 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;
   

以上是关于F - Sorting a Matrix(拓扑&缩点)的主要内容,如果未能解决你的问题,请参考以下文章

拓扑排序(Topological Sorting)

poj1094-Sorting It All Out-拓扑排序

POJ1094-Sorting It All Out-拓扑排序

POJ 1094 Sorting It All Out(拓扑排序+判环+拓扑路径唯一性确定)

Sorting It All Out(拓扑排序)

Sorting It All Out (拓扑排序+思维)