码迷,mamicode.com
首页 > 其他好文 > 详细

Gym - 101503I 利用到图论的构造

时间:2017-10-10 16:35:21      阅读:168      评论:0      收藏:0      [点我收藏+]

标签:main   ++   必须   push   合法性   比赛   void   nbsp   top   

比赛的时候没有注意到 给出的up矩阵 能使我们随便选一列 确定这一列的rank

这样我们得出每一行列的rank 进行构图 大->小 然后从大到小放 当前放的点 和他有因果关系并且比他大的点必须已经被放了 并且这个图没有环

做一个topsort就可以了

但是会MLE 因为边的数量可能 600^3 这个图虽然满足拓扑图 但是它比拓扑图更满足一个严格的等级序列

所以可以只建600^2的边 每个点指向只比它小的点

需要判断输入的合法性

int n ;
int le[605][605] ;
int up[605][605] ;
int d[605][605] ;
int deg[605*605] ;
int ans[605][605] ;

int head[605 * 605] ;
struct edge{
    int v,nex;
}b[605 * 605 * 2] ;
int tot ;
void add(int u,int v){
    tot ++ ;
    b[tot].v=v ; b[tot].nex=head[u];
    head[u]=tot ;
}

bool topso() {
    int cnt = n*n ;
    queue<int>que ;
    while(!que.empty()) que.pop() ;
    rep(i,1,n*n) {
        if(deg[i] == 0) {
            que.push(i) ;
        }
    }
    while(!que.empty()) {
        int u = que.front() ; que.pop() ;
        int x = (u+n-1)/n;
        int y = (u%n) ; if(y==0)y=n;
        ans[x][y] = cnt -- ;
        rnode(i,u){
            int v=b[i].v;
            deg[v]--;
            if(deg[v]==0){
                que.push(v) ;
            }
        }
    }
    return cnt == 0 ;
}

int main () {
    tot = 0 ;
    flc(head,-1) ;
    n = read() ;
    rep(i,1,n) rep(j,1,n) up[i][j] = read() ;
    rep(i,1,n) rep(j,1,n) le[i][j] = read() ;
    rep(i,1,n) rep(j,1,n) {
        if(up[i][j] >= i || le[i][j] >= j) {
            printf("0\n") ; return 0 ;
        }
    }
    rep(i,1,n) rep(j,1,n) d[i][j] = (i-1)*n + j ;
    flc(deg,0) ;
    rep(i,1,n) {
        int a[650] ;
        a[1] = d[i][1] ;
        rep(j,2,n) {
            int m = le[i][j] ;
            m ++ ;
            dow(k,j,m+1) a[k] = a[k-1] ;
            a[m] = d[i][j] ;
        }
        rep(j,1,n-1) {
            add(a[j],a[j+1]) ;
            deg[a[j+1]] ++ ;
        }
    }
    rep(j,1,n) {
        int a[650] ;
        a[1] = d[1][j] ;
        rep(i,2,n) {
            int m = up[i][j] ;
            m ++ ;
            dow(k,i,m+1) a[k] = a[k-1] ;
            a[m] = d[i][j] ;
        }
        rep(i,1,n-1) {
            add(a[i],a[i+1]) ;
            deg[a[i+1]] ++ ;
        }
    }
    if(topso()) {
        rep(i,1,n) rep(j,1,n) {
            printf("%d" , ans[i][j]) ; fmt(j,n) ;
        }
    }
    else {
        printf("0\n") ;
    }
}

 

Gym - 101503I 利用到图论的构造

标签:main   ++   必须   push   合法性   比赛   void   nbsp   top   

原文地址:http://www.cnblogs.com/rayrayrainrain/p/7645385.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!