POJ: 1128 Frame Stacking (全拓扑序列)

题意:给一幅图是几张图叠起来以后的效果,问这几张图是按照什么顺序叠起来的。

思路:由于每张图四条边都至少能看见一个字符,由此可以推出该图片的大小,在该图片边界上出现的图片就是覆盖它的图片,由此建图,输出全拓扑序列。

1Y。可能细节比较多一点。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
#include <vector>
#include <stack>
#define MAXN 1000
using namespace std;
typedef struct CsNode
{
    int data;
    bool vis;
    CsNode *parent,*firstchild,*nextsibling;
} CsNode,*toptree;
int n;
int in[MAXN];
char val[MAXN];
void process(vector<int> gl[],stack<int> &sk,int p)
{
    in[p]--;
    for(int i=0; i<gl[p].size(); ++i)
        in[gl[p][i]]--;
    for(int i=0; i<n; ++i)
        if(!in[i]) sk.push(i);
}
void addinagree(vector<int> gl[],int p)
{
    in[p]++;
    for(int i=0; i<gl[p].size(); ++i)
        in[gl[p][i]]++;
}
void createtoptree(vector<int> gl[])
{
    CsNode *head;
    head=new CsNode;
    head->data=head->vis=head->vis=head->parent=head->firstchild=head->nextsibling=NULL;
    CsNode *T;
    T=head;
    stack<int> sk;
    int cd[MAXN]= {0},cdlen=0;
    for(int i=0; i<n; ++i)
        if(!in[i]) sk.push(i);
    CsNode *p;
    while(!sk.empty())
    {
        while(!sk.empty())
        {
            while(!sk.empty())
            {
                int gettop=sk.top();
                sk.pop();
                p=new CsNode;
                p->parent=T;
                p->firstchild=NULL;
                p->data=gettop;
                p->vis=false;
                p->nextsibling=T->firstchild;
                if(p->nextsibling) p->nextsibling->parent=p;
                T->firstchild=p;
            }
            T=T->firstchild;
            int pos=T->data;
            cd[cdlen++]=pos;
            process(gl,sk,pos);
        }
        cd[cdlen]=-1;
        int k=0;
        while(cd[k]!=-1)
        {
            char c=val[cd[k]];
            printf("%c",c);
            k++;
        }
        printf("\n");
        while((p->nextsibling==0||p->vis==true)&&p->parent!=0)
        {
            if(p->vis==false)
            {
                int pos=p->data;
                addinagree(gl,pos);
                cdlen--;
            }
            p->vis=false;
            CsNode *q=p;
            p=p->parent;
            delete q;
        }
        if(p->nextsibling&&!p->vis)
        {
            p->vis=true;
            int pos=p->data;
            addinagree(gl,pos);
            cdlen--;
            T=p->nextsibling;
            pos=T->data;
            cd[cdlen++]=pos;
            process(gl,sk,pos);
        }
    }
}
struct Rectangle
{
    char name;
    int u,d,l,r;
    Rectangle()
    {
        u=50;
        l=50;
        d=-50;
        r=-50;
    }
    void cmp(int i,int j)
    {
        u=min(u,i);
        d=max(d,i);
        l=min(l,j);
        r=max(r,j);
    }
    bool operator < (Rectangle r) const
    {
        return name<r.name;
    }
};
void addedge(int v,int u,vector<int> gl[])
{
    if(gl[u].end()==find(gl[u].begin(),gl[u].end(),v))
    {
        in[v]++;
        gl[u].push_back(v);
    }
}
int main()
{
    int h,w;
    while(scanf("%d%d",&h,&w)!=EOF)
    {
        char grid[35][35]= {0};
        for(int i=0; i<h; ++i)
            scanf("%s",grid[i]);
        n=0;
        map<char ,int > cur;
        map<char ,bool > appear;
        Rectangle rec[MAXN];
        for(int i=0; i<h; ++i)
            for(int j=0; j<w; ++j)
            {
                char c=grid[i][j];
                if(c!='.')
                {
                    if(!appear[c])
                    {
                        appear[c]=true;
                        rec[n].name=c;
                        cur[c]=n++;
                    }
                    int pos=cur[c];
                    rec[pos].cmp(i,j);
                }
            }
        memset(val,0,sizeof(val));
        memset(in,0,sizeof(in));
        sort(rec,rec+n);
        map<char,int> mp;
        for(int i=0; i<n; ++i)
        {
            val[i]=rec[i].name;
            mp[rec[i].name]=i;
        }
        vector<int> g[MAXN];
        for(int i=0; i<n; ++i)
        {
            char c=rec[i].name;
            int u=rec[i].u,l=rec[i].l,r=rec[i].r,d=rec[i].d;
            for(int j=l; j<=r; ++j)
            {
                char uu=grid[u][j],dd=grid[d][j];
                if(uu!=c&&uu!='.') addedge(mp[uu],mp[c],g);
                if(dd!=c&&dd!='.') addedge(mp[dd],mp[c],g);
            }
            for(int j=u; j<=d; ++j)
            {
                char ll=grid[j][l],rr=grid[j][r];
                if(ll!=c&&ll!='.') addedge(mp[ll],mp[c],g);
                if(rr!=c&&rr!='.') addedge(mp[rr],mp[c],g);
            }
        }
        createtoptree(g);
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值