P7860-题解
题面:
这里
分析:
假定要使某根木棍向下移动,且不碰到其他木棍,那我们要使得这根木棍下其他木棍比他先移动。
我们可以在此基础上建立一个有向图:如果木棍
最后的答案就是这个图的拓扑序
Code
#include <iostream>
#include <cstdio>
#include <vector>
#include <queue>
using namespace std;
struct node{
int x1,x2,y1,y2;
}a[5005];//存储木棍的信息
queue<int> q;
const int N=5005*5005/2;
int n,d[5005],ver[5005],to[N],nxt[N],idx;
void add(int x,int y){
to[++idx]=y,nxt[idx]=ver[x],ver[x]=idx;
}
int pd(node u,node v){ //判断木棒的相对位置,最核心的代码
int f=1;
if(u.x1>v.x1) swap(u,v),f=-f;
if(u.x2<v.x1) return 0;
double k,B,yy;
if(!(u.x2-u.x1)){
k=1.0*(v.y2-v.y1)/(v.x2-v.x1);
B=(double)v.y1-k*v.x1;
yy=k*u.x1+B;
if(u.y1>yy) return f;
return -f;
}
k=1.0*(u.y2-u.y1)/(u.x2-u.x1);
B=(double)u.y1-k*u.x1;
yy=k*v.x1+B;
if(yy>v.y1) return f;
return -f;
}
void topsort(){//拓扑排序板子
for(int i=1;i<=n;i++){
if(!d[i]){
cout<<i<<" ";
q.push(i);
}
}
while(q.size()){
int t=q.front();q.pop();
for(int i=ver[t];i;i=nxt[i]){
int tp=to[i];
d[tp]--;
if(d[tp]==0){
cout<<tp<<" ";
q.push(tp);
}
}
}
return;
}
int main(){
cin>>n;
for(int i=1;i<=n;i++){
scanf("%d %d %d %d",&a[i].x1,&a[i].y1,&a[i].x2,&a[i].y2);
if(a[i].x1>a[i].x2)swap(a[i].x1,a[i].x2),swap(a[i].y1,a[i].y2);//让两个端点有先后顺序
}
for(int i=1;i<n;i++){
for(int j=i+1;j<=n;j++){
int p=pd(a[i],a[j]);
if(p==1)add(j,i),d[i]++;
if(p==-1)add(i,j),d[j]++;//建图
}
}
topsort();
return 0;
}
如有错误,请指出。