题目链接HDU-3231
题是好题,就是输出格式略坑。。少空行他不会提示PE只显示WA
对于给定的n个盒子,我们可以将其起始点和终点分别假定为i和i+n,
这样我们就可以在每个维度(x,y,z)上得到2n个点
在初始化的时候,考虑初始约束条件
x<x+n,y<y+n,z<z+n 在初始时已经就应该要连边,需要单独初始化
然后考虑“I”,“X”,“Y”,“Z”的询问更新,
当为“I”时,a,b没有相交关系,在三个维度上添加约束条件a<b+n,b<a+n(这个约束条件非常巧妙)
当为“X”,“Y”,“Z”时,给a,b在相应维度上连边 “a+n<b”;
按照对应约束条件完成建图
再对三个维度分别跑一次拓扑排序即可
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <map>
#include <queue>
#include <functional>
#include <vector>
#include <stack>
#include <set>
#include <bitset>
using namespace std;
typedef long long ll;
const int maxn=2e5+50;
const int inf=0x7fffffff;
const int mod=1e9+7;
const int HASH=131;
vector<int> v[3][maxn];//代表维度分别为xyz
int degree[3][maxn];
int dis[3][maxn];
void init(int n)
{
for(int i=0;i<3;i++)
{
for(int j=1;j<=2*n;j++)
{
degree[i][j]=dis[i][j]=0;
v[i][j].clear();
}
}
for(int i=0;i<3;i++)
{
for(int j=n+1;j<=2*n;j++)
{
degree[i][j]++;
v[i][j-n].push_back(j);
}
}
}
int main()
{
int n,m;
int cass=1;
while(scanf("%d%d",&n,&m)!=EOF&&n+m)//初始将最大的盒子长度定为n
{
init(n);
for(int ttt=1;ttt<=m;ttt++)
{
char s[5];
int a,b;
scanf("%s %d %d",s,&a,&b);
if(s[0]=='I')
{
for(int i=0;i<3;i++)
{
v[i][a].push_back(b+n);
degree[i][b+n]++;
v[i][b].push_back(a+n);
degree[i][a+n]++;
}
}
else if(s[0]=='X')
{
v[0][a+n].push_back(b);
degree[0][b]++;
}
else if(s[0]=='Y')
{
v[1][a+n].push_back(b);
degree[1][b]++;
}
else if(s[0]=='Z')
{
v[2][a+n].push_back(b);
degree[2][b]++;
}
}
printf("Case %d: ",cass++);
int sign=0;
for(int i=0;i<3;i++)
{
queue<int> q;
int cnt=0;//统计进入队列数量,并给距离赋初始值
for(int j=1;j<=n;j++)
{
if(degree[i][j]==0)
{
q.push(j);
dis[i][j]=cnt++;
}
}
while(!q.empty())//找每个维度上入度为0的点
{
int tmp=q.front();
q.pop();
int len=v[i][tmp].size();
for(int j=0;j<len;j++)
{
int t=v[i][tmp][j];
dis[i][t]=max(dis[i][t],dis[i][tmp]+1);//让距离满足约束条件
if(--degree[i][t]==0)
{
q.push(t);
cnt++;
}
}
}
if(cnt!=2*n) sign=1;
}
if(sign)
{
printf("IMPOSSIBLE\n");
}
else
{
printf("POSSIBLE\n");
for(int i=1;i<=n;i++)
{
printf("%d %d %d %d %d %d\n",dis[0][i],dis[1][i],dis[2][i],dis[0][i+n],dis[1][i+n],dis[2][i+n]);
}
}
cout<<endl;
}
return 0;
}
本文提供HDU-3231题目的详细解答过程,通过建立三维拓扑排序模型来解决盒子堆叠问题。文章介绍了如何初始化约束条件、处理不同类型的询问并实现拓扑排序算法。
13万+

被折叠的 条评论
为什么被折叠?



