北大1128题

来源:互联网 发布:java标准时间格式 编辑:程序博客网 时间:2024/05/18 17:02

 题目连接:http://acm.pku.edu.cn/JudgeOnline/problem?id=1128

1,用acr[MAX][MAX]存储图,但是有效节点可能并不连续地存在,借助in[MAX]数组表示有效节点

2,将问题转换成拓扑排序是问题的关键,转换可以实施的条件是:从叠放图中总可以提取出所有叠放对象的边框信息;找到一个边框信息后,这个边框上出现的其它边框信息就时覆盖在这个边框上的边框那么可以在当前边框和覆盖当前边框的边框之间画一条有向弧,表示从下到上的先后序关系;依据这两条可以建图

3,建好图后要按字典序输出图的所有可能的拓扑序列,这主要用到回溯法设计思想,假设当前顶点的入度信息为indeg[MAX],从中按照字典序搜索in[MAX]为true的顶点,找到一个indeg[i]为0的点就删除它为了避免重复输出需要用indeg[i]=1来标示它已被删除,然后再去递归地删除其它入度为0的点。indeg[i]为0时可能存在其它入度为0的顶点,这就需要保存上下文,以便回溯到这里时再在相同的环境下删除其它入度为0的点得到所有可能的拓扑序列!

#include <iostream>
using namespace std;

#define MAX 26
#define MAX_H 30
#define MAX_W 30

struct Graph
{
 bool arc[MAX][MAX];
 int v_num;

 char ans[MAX];
 int a_num;

 bool in[MAX];
 int indeg[MAX];

 void Init()
 {
  v_num = 0;
  a_num = 0;
  memset(arc,0,sizeof(arc));
  memset(in,0,sizeof(in));
  memset(indeg,0,sizeof(indeg));
 }
};

void AllTopSort(Graph& g)
{
 if(g.a_num == g.v_num)
 {
  g.ans[g.a_num] = '/0';
  cout << g.ans << endl;
 }
 else
 {
  int i,j;
  int backup[MAX];
  for(i = 0;i < MAX;++i)
  {
   if(g.in[i] && g.indeg[i] == 0)
   {
    for(j = 0;j < MAX;++j)
     backup[j] = g.indeg[j];
    g.ans[g.a_num] = i + 'A';
    ++g.a_num;

    g.indeg[i] = 1;
    for(j = 0;j < MAX;++j)
    {
     if(g.in[j] && g.arc[i][j])
      --g.indeg[j];
    }
    AllTopSort(g);
    
    for(j = 0;j < MAX;++j)
     g.indeg[j] = backup[j];
    --g.a_num;
   }
  }
 }
}

int main()
{
 freopen("in.txt","r",stdin);

 char map[MAX_H][MAX_W];
 int rws,cls;
 
 Graph g;
 int i,j,k,lf,tp,rt,dn;
 while(cin >> rws >> cls)
 {
  for(i = 0;i < rws;++i)
  {
   for(j = 0;j < cls;++j)
    cin >> map[i][j];
  }
  
  g.Init();
  for(i = 'A';i <= 'Z';++i)
  {
   lf = tp = 30;
   rt = dn = -1;
   for(j = 0;j < rws;++j)
   {
    for(k = 0;k < cls;++k)
    {
     if(map[j][k] == char(i))
     {
      if(tp > j)
       tp = j;
      if(dn < j)
       dn = j;
      if(lf > k)
       lf = k;
      if(rt < k)
       rt = k;
     }
    }
   }

   if(rt != -1)
   {
    g.in[i-'A'] = true;
    for(j = tp;j <= dn;++j)
    {
     if(map[j][lf] != '.' && map[j][lf] != char(i))
     {
      g.in[map[j][lf]-'A'] = true;
      g.arc[i-'A'][map[j][lf]-'A'] = true;
     }
     if(map[j][rt] != '.' && map[j][rt] != char(i))
     {
      g.in[map[j][rt]-'A'] = true;
      g.arc[i-'A'][map[j][rt]-'A'] = true;
     }
    }

    for(j = lf;j <= rt;++j)
    {
     if(map[tp][j] != '.' && map[tp][j] != char(i))
     {
      g.in[map[tp][j]-'A'] = true;
      g.arc[i-'A'][map[tp][j]-'A'] = true;
     }
     if(map[dn][j] != '.' && map[dn][j] != char(i))
     {
      g.in[map[dn][j]-'A'] = true;
      g.arc[i-'A'][map[dn][j]-'A'] = true;
     }
    }
   }
  }

  for(i = 0;i < MAX;++i)
  {
   if(g.in[i])
    ++g.v_num;
  }

  for(i = 0;i < MAX;++i)
  {
   for(j = 0;j < MAX;++j)
   {
    if(g.arc[i][j])
     ++g.indeg[j];
   }
  }

  AllTopSort(g);
 }
 return 0;
}

原创粉丝点击