【拓扑排序】Gym - 101503 - I.Just Matrix

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/monochrome00/article/details/83624889

题目链接<http://codeforces.com/gym/101503/problem/I>


题意:

有一个n*n的矩阵,里面的数字为1~n*n,给出每个位置在它上边和左边有多少个大于它的数。构造出这么一个矩阵。


题解:

可以得知每一行每一列的大小顺序,每一行每一列从小到大依次连边。

如果从小到大依次填入数字,这样就能够确定因果关系。

然后做一次拓扑排序判断有无结果并输出即可。


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=6e2+7;
const int M=1e6+7;
int a[N][N],b[N][N],n;
int od[N];
struct Edge{
    int u,v,nxt;
    Edge(int u=0,int v=0,int nxt=0):u(u),v(v),nxt(nxt){}
}e[M];
int p[M],edn;
void add(int u,int v){
    e[++edn]=Edge(u,v,p[u]);p[u]=edn;
}
int ans[N][N],d[N*N];
bool Tsort(){
    queue<int>q;
    for(int i=0;i<n*n;i++){
        if(d[i]==0) q.push(i);
    }
    int cnt=0;
    while(!q.empty()){
        int u=q.front();q.pop();
        ans[u/n][u%n]=++cnt;
        for(int i=p[u];~i;i=e[i].nxt){
            int v=e[i].v;
            d[v]--;
            if(d[v]==0) q.push(v);
        }
    }
    if(cnt<n*n) return false;
    return true;
}
int main()
{
    memset(p,-1,sizeof(p));edn=-1;
    scanf("%d",&n);
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
            scanf("%d",&a[i][j]);
    bool flag=true;
    for(int j=0;j<n;j++){
        memset(od,-1,sizeof(od));
        for(int i=n-1;i>=0;i--){
            int tmp=a[i][j];
            int id=i*n+j;
            int k=n-1;
            while(tmp&&k>=0){
                if(od[k]==-1) tmp--;
                k--;
            }
            while(od[k]!=-1&&k>=0) k--;
            if(k<0){flag=false;break;}
            else od[k]=id;
        }
        if(!flag) break;
        for(int k=0;k<n-1;k++){
            add(od[k],od[k+1]);
            d[od[k+1]]++;
        }
    }
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
            scanf("%d",&b[i][j]);
    for(int i=0;i<n;i++){
        memset(od,-1,sizeof(od));
        for(int j=n-1;j>=0;j--){
            int tmp=b[i][j];
            int id=i*n+j;
            int k=n-1;
            while(tmp&&k>=0){
                if(od[k]==-1) tmp--;
                k--;
            }
            while(od[k]!=-1&&k>=0) k--;
            if(k<0){flag=false;break;}
            else od[k]=id;
        }
        if(!flag) break;
        for(int k=0;k<n-1;k++){
            add(od[k],od[k+1]);
            d[od[k+1]]++;
        }
    }
    if(!flag||!Tsort()){printf("0\n");return 0;}
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++)
            printf("%d ",ans[i][j]);
        printf("\n");
    }
}

猜你喜欢

转载自blog.csdn.net/monochrome00/article/details/83624889