• POJ 1128DAG拓扑排序


    题目链接POJ1128

    题意

    给定一张边框覆盖图,求边框从上到下的关系

    分析

    如果在A的边框上出现了字母B,就说明B在A的上方

    如果边框A在边框B的下方,就添加从A到B的一条有向边(题目要求从下到上输出)

    那么所求的是所得有向无环图的拓扑排序

    题目还要求按照字典序输出所有可能的顺序,用深度优先搜索

    代码

    #include <cstdio>
    #include <cstring>
    #include <vector>
    #include <cmath>
    #include <iostream>
    #include <algorithm>
    #define MAX 1000007
    #define MAXN 50
    #define MAXM 1007
    #define INF  0x3f3f3f3f
    #define NINF 0xc0c0c0c0
    #define MOD 1000000007
    using namespace std;
    typedef long long LL;
    int head[MAXN],tot,n,m,indegree[MAXN],realn;
    
    struct Edge{
        int to;
        int next;
    }edge[MAXM];
    
    void addEdge(int u,int v){
        edge[tot].to=v;
        indegree[v]++;
        edge[tot].next=head[u];
        head[u]=tot++;
    }
    
    int visit[MAXN],Map[40][40],flag[40][40],df[MAXN];
    struct Border{
        int x1,y1,x2,y2;
    }border[MAXN];
    
    int Queue[MAXN],iq;
    
    void init(){
        tot=iq=realn=0;
        memset(head,-1,sizeof head);
        memset(visit,0,sizeof visit);
        memset(Map,0,sizeof Map);
        memset(flag,0,sizeof flag);
        memset(indegree,0,sizeof indegree);
        memset(df,0,sizeof df);
        for(int i=0;i<MAXN;i++){
            border[i].x1=border[i].y1=40;
            border[i].x2=border[i].y2=-1;
        }
    }
    
    //如果字母t在字母k的四条边框上,则连接k到t的有向边(从下到上的方向) 
    void addE(int k,int x1,int y1,int x2,int y2){
        for(int i=x1;i<=x2;i++){
            for(int j=y1;j<=y2;j++){
                int t=Map[i][j];
                if(k!=t && !flag[k][t]){
                    flag[k][t]=1;
                    addEdge(k,t);
                }
            }
        }
    }
    
    //深度优先遍历出所有的拓扑排序 
    void dfs(int now,int k){
        //cout<<now<<" "<<k<<endl;
        if(k==realn){
            for(int i=1;i<=realn;i++){
                printf("%c", Queue[i]+'A'-1);
            }
            printf("\n");
        }
        else{
            //删掉与now关联的边 
            for(int i=head[now];i!=-1;i=edge[i].next){
                indegree[edge[i].to]--;
            }
            //从剩余的点中选择入度为0的点,从小到大遍历 
            for(int i=1;i<MAXN;i++){
                if(!df[i]&&visit[i]&&indegree[i]==0){
                    df[i]=1;
                    Queue[k+1]=i;
                    dfs(i,k+1);
                    df[i]=0;
                }
            }
            //加回与now关联的边 
            for(int i=head[now];i!=-1;i=edge[i].next){
                indegree[edge[i].to]++;
            }
        }
    }
    
    int main(){
        char ch;
        while(scanf("%d%d",&n,&m)==2){
            init();
            for(int i=0;i<n;i++){
                for(int j=0;j<m;j++){
                    scanf(" %c",&ch);
                    if(ch!='.'){
                        Map[i][j]=ch-'A'+1;
                    }
                }
            }
            for(int i=0;i<n;i++){
                for(int j=0;j<m;j++){
                    int t=Map[i][j];
                    if(t){
                        visit[t]=1;
                        border[t].x1=min(border[t].x1,i);
                        border[t].y1=min(border[t].y1,j);
                        border[t].x2=max(border[t].x2,i);
                        border[t].y2=max(border[t].y2,j);
                    }
                }
            }
            for(int k=1;k<30;k++){
                if(visit[k]){
                    addE(k,border[k].x1,border[k].y1,border[k].x1,border[k].y2);
                    addE(k,border[k].x2,border[k].y1,border[k].x2,border[k].y2);
                    addE(k,border[k].x1,border[k].y1,border[k].x2,border[k].y1);
                    addE(k,border[k].x1,border[k].y2,border[k].x2,border[k].y2); 
                }
            }
            //cout<<tot<<endl;
            for(int i=1;i<=30;i++){
                if(visit[i]){
                    realn++;
                    addEdge(0,i);
                }
            }
            //cout<<realn<<endl;
            dfs(0,0);
        }
        return 0;
    }
    /*
    6 6
    BBBCCC
    BAAAAC
    BABCAC
    .ADDA.
    .AAAA.
    ..DD..
    */
    View Code
  • 相关阅读:
    better-scroll 介绍
    promise 异步编程
    vue网址路由的实时检测
    浏览器本地存储的使用
    获取元素的位置
    如何设置动画的运动效果
    实现对称加密及非对称公钥加密
    Centos 7系统启动修复
    Centos 7服务启动文件
    内核编译-4.12
  • 原文地址:https://www.cnblogs.com/shuiming/p/7034014.html
Copyright © 2020-2023  润新知