ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

CF1500C Matrix Sorting(拓扑排序)

2021-11-17 13:32:43  阅读:183  来源: 互联网

标签:Sorting return Matrix int ++ vis printf du CF1500C


解析

神仙题
我想到了一部分,但是由于没想到倒着做,后面越想越复杂…

本题的关键是要倒着想
考虑最后一次排序的列x
必须是单调不增的
否则直接错
然后倒数第二列y
必须在x列相等的段内单调不增,因为这些地方x无法起到排序的作用
同理再到倒数第三列…

那么这个怎么实现呢?
拓扑排序!
考虑一列中肯定有一些相邻的逆序对
如果这个逆序对已经被前面的覆盖过,就没关系
一个列如果所有的逆序对都被覆盖,就可以使用了

考虑将列操作和相邻行分别看作点,连边即可
逆序对只要被遍历到即可入队
列操作只有入度减为0才能入队

代码

#include<bits/stdc++.h>

const int N=1550;
const int mod=1e9+7;
#define ll long long
#define ull unsigned long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
using namespace std;
inline ll read() {
  ll x(0),f(1);char c=getchar();
  while(!isdigit(c)) {if(c=='-')f=-1;c=getchar();}
  while(isdigit(c)) {x=(x<<1)+(x<<3)+c-'0';c=getchar();}
  return x*f;
}

const int key=13331;

int n,m;

struct node{
  int to,nxt;
}p[N*N*2];
int fi[N<<2],cnt;
inline void addline(int x,int y){
  p[++cnt]=(node){y,fi[x]};fi[x]=cnt;
  return;
}
bool vis[N<<2];
int du[N<<2],q[N<<2],st,ed;

int a[N][N],b[N][N];
ull h1[N],h2[N];
void Hash(){
  for(int i=1;i<=n;i++){
    for(int j=1;j<=m;j++) h1[i]=h1[i]*key+a[i][j];
  }
  for(int i=1;i<=n;i++){
    for(int j=1;j<=m;j++) h2[i]=h2[i]*key+b[i][j];
  }
  for(int i=1;i<=n;i++){
    for(int j=1;j<=n;j++){
      if(b[j][m+1]) continue;
      if(h1[i]==h2[j]){
	b[j][m+1]=i;break;
      }
      if(j==n){
	printf("-1\n");exit(0);
      }
    }
  }
  return;
}
int ans[N],num;
int main(){
#ifndef ONLINE_JUDGE
  freopen("a.in","r",stdin);
  freopen("a.out","w",stdout);
#endif
  memset(fi,-1,sizeof(fi));cnt=-1;
  n=read();m=read();
  for(int i=1;i<=n;i++){
    for(int j=1;j<=m;j++) a[i][j]=read();
  }
  for(int i=1;i<=n;i++){
    for(int j=1;j<=m;j++) b[i][j]=read();
  }
  Hash();
  //debug("OK\n");
  //for(int i=1;i<=n;i++){
  //for(int j=1;j<=m+1;j++) printf("%d ",b[i][j]);
  //putchar('\n');
  //}
  for(int i=1;i<n;i++){
    for(int j=1;j<=m+1;j++){
      if(b[i][j]<b[i+1][j]) addline(j+n,i);
      else if(b[i][j]>b[i+1][j]){
	//printf("(%d %d)\n",i,j);
	addline(i,j+n),du[j+n]++;
      }
    }
  }
  st=1;
  for(int i=n+1;i<=n+m+1;i++){
    //printf("i=%d du=%d\n",i-n,du[i]);
    if(!du[i]) q[++ed]=i,vis[i]=1;
  }
  while(st<=ed){
    int now=q[st++];
    if(now==n+m+1) break;
    if(now>n&&now<=n+m) ans[++num]=now-n;
    for(int i=fi[now];~i;i=p[i].nxt){
      int to=p[i].to;
      if(vis[to]) continue;
      if(to<n) q[++ed]=to,vis[to]=1;
      if(to>n&&--du[to]==0) q[++ed]=to,vis[to]=1;
    }
  }
  if(!vis[n+m+1]){
    printf("-1\n");return 0;
  }
  else{
    printf("%d\n",num);
    while(num) printf("%d ",ans[num--]);
    return 0;
  }
  return 0;
}
/*
  5 3
  7 1 4 1 9 
  1 3 5 3
  1 1 4 2
  2 3 5
*/

标签:Sorting,return,Matrix,int,++,vis,printf,du,CF1500C
来源: https://blog.csdn.net/BUG_Creater_jie/article/details/121375874

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有