您的位置:首页 > 其它

Frame Up_usaco 4.4_拓扑排序

2016-12-01 16:35 399 查看

Description

看下面的五张 9 x 8 的图像:



现在,把这些图像按照 1—5 的编号从下到上重叠,第 1 张在最下面,第 5 张在最顶端。如果一张图像覆盖了另外一张图像,那么底下的图像的一部分就变得不可见了。我们得到下面的图像:



对于这样一张图像,计算构成这张图像的矩形图像从底部到顶端堆叠的顺序。

下面是这道题目的规则:

• 矩形的边的宽度为 1 ,每条边的长度都不小于 3 。

• 矩形的每条边中,至少有一部分是可见的。注意,一个角同时属于两条边。

• 矩形用大写字母表示,并且每个矩形的表示符号都不相同。

Input

第一行 两个用空格分开的整数:图像高 H (3 <= H <=30) 和图像宽 W (3 <= W <= 30) 。

第二行到第 H+1 行 H 行,每行 W 个字母。

Output

按照自底向上的顺序输出字母。如果有不止一种情况,按照字典顺序输出每一种情况(至少会有一种合法的顺序)。

Analysis

我tm又双叒叕被usaco恶心到了

首先确定每个字母所在矩形,如果在A字母的矩形上找到了B字母,那么连边B->A,然后就是拓扑排序

需要注意的是拓扑序不唯一,所以我们需要枚 暴 举 搜 所有可能的拓扑序然后记录解,最后排序

打完才觉得不算难的一题

Code

/*
ID:wjp13241
PROG:frameup
LANG:C++
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#define fo(i,a,b) for (int i=a;i<=b;i++)
#define dfo(i,a,b) for (int i=a;i>=b;i--)
#define fil(x,t) memset(x,t,sizeof(x))
#define STP system("pause")
#define min(x,y) x<y?x:y
#define max(x,y) x>y?x:y
#define ll long long
#define INF 0x7f7f7f7f
#define EPS 1e-4
#define L 351
#define N 351
#define E N*N+1
using namespace std;
struct word{int u,d,l,r;}t[27];
struct edge{int y,next;}e[E];
string ans[E];
int p

,vis
,map

,ls[E],ind
,bct[27],maxE=0,num=0;
int add(int x,int y){e[++maxE]=(edge){y,ls[x]},ls[x]=maxE;};
int topsort(string lis,int cnt,int tot)
{
if (cnt==tot)
{
ans[++num]=lis;
return 0;
}
fo(x,1,26)
if (!ind[x]&&t[x].d)
{
for (int i=ls[x];i;i=e[i].next)
ind[e[i].y]--;
ind[x]=-1;
topsort((char)(x-1+'A')+lis,cnt+1,tot);
ind[x]=0;
for (int i=ls[x];i;i=e[i].next)
ind[e[i].y]++;
}
}
int main()
{
ios::sync_with_stdio(false);
int n,m;
cin>>n>>m;
fo(i,1,26)
t[i]=(word){INF,0,INF,0};
fo(i,1,n)
{
char s[L];
cin>>s;
fo(j,0,m-1)
{
if (s[j]!='.')
map[i][j+1]=s[j]-'A'+1;
else
map[i][j+1]=0;
t[map[i][j+1]]=(word){min(t[map[i][j+1]].u,i),max(t[map[i][j+1]].d,i),min(t[map[i][j+1]].l,j+1),max(t[map[i][j+1]].r,j+1)};
}
}
int tot=0;
fo(i,1,26)
if (t[i].d)
{
tot++;
fo(k,t[i].u,t[i].d)
{
int now=map[k][t[i].l];
if (now&&now!=i&&!p[now][i])
{
p[now][i]=1;
add(now,i);
ind[i]++;
}
now=map[k][t[i].r];
if (now&&now!=i&&!p[now][i])
{
p[now][i]=1;
add(now,i);
ind[i]++;
}
}
fo(k,t[i].l,t[i].r)
{
int now=map[t[i].u][k];
if (now&&now!=i&&!p[now][i])
{
p[now][i]=1;
add(now,i);
ind[i]++;
}
now=map[t[i].d][k];
if (now!=i&&!p[now][i])
{
p[now][i]=1;
add(now,i);
ind[i]++;
}
}
}
topsort("",0,tot);
sort(ans+1,ans+num+1);
fo(i,1,num)
cout<<ans[i]<<endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: