http://acm.hdu.edu.cn/showproblem.php?pid=3231
拓扑排序,真正应用,还是不怎么会呀!!!再加上这个题的图的构建,就更加麻烦了!!
此题的意思总是看不明白,最后也没有能想明白,大致是这个意思吧:
把一个箱子分成三个面,即X,Y,Z
拿X来说,把这个面分为上下两部分,上面记为1,下面记为1+n,当读入X A B条件的时候,那么A箱的下表面和B箱的上表面构成关系,虽然题目中说是A要比B小,但是由于我们最后记录的时候i是从小到大来的,所以我们把A放在B的上面,结果是A的坐标比B小。
总之是贴别人的代码,为我所用了。
#include <stdio.h>
#include <string.h>
#define MAX 2005
#define M 500000
#define bool int
int degree[4][MAX];
int n, r, NE;
struct node
{
int v;
int next;
}e[M];
int head[4][MAX], q[4][MAX], ans[4][MAX];
void insert(int type, int u, int v)
{
e[NE].next = head[type][u];
e[NE].v = v;
head[type][u] = NE ++;
degree[type][v] ++;
}
void init()
{
int i, j;
NE = 0;
memset(degree, 0, sizeof(degree));
memset(head, -1, sizeof(head));
for(i = 1; i <= n; i ++){
for(j = 1; j <= 3; j ++){
insert(j, i, i + n);
}
}
}
bool topsort(int type)
{
int front = 0, top = 0, i, u, v;
for(i = 1; i <= n*2; i ++){
if(degree[type][i] == 0){
q[type][top ++] = i;
degree[type][i] --;
}
}
while(front < top){
u = q[type][front++];
for(i = head[type][u]; i != -1; i = e[i].next){
v = e[i].v;
degree[type][v]--;
if(degree[type][v] == 0){
q[type][top++] = v;
degree[type][v] --;
}
}
}
return top==2*n;
}
void solve()
{
int i, j;
for(i = 1; i <= 3; i ++){
if(!topsort(i)){
printf(" IMPOSSIBLE\n");
return;
}
}
printf(" POSSIBLE\n");
for(i = 0; i < 2*n; i ++){//注意的地方
for(j = 1; j <= 3; j ++){
ans[j][q[j][i]] = i;
}
}
for(i = 1; i <= n; i ++){
printf("%d %d %d %d %d %d\n", ans[1][i], ans[2][i], ans[3][i], ans[1][i+n], ans[2][i+n], ans[3][i+n]);
}
}
int main()
{
int cnt = 1;
char str[2];
int a, b, i;
while(scanf("%d%d", &n,&r)&&n+r){
init();
while(r--){
scanf("%s%d%d", str, &a, &b);
if(str[0] == 'I'){
for(i = 1; i <= 3; i ++){
insert(i, a, b+n);
insert(i, b, a+n);
}
}
else insert(str[0]-'X'+1, a+n, b);
}
printf("Case %d:", cnt++);
solve();
printf("\n");
}
return 0;
}