题目的大致意思是说,给定n个点的座标,让我们求起点到终点的最短距离.
点点之间的距离是min(abs(x1-x2),abs(y1-y2))
一开始根本不会写.直到看到了博主:http://blog.csdn.net/octopusflying/article/details/51125562的代码
思路大体是,从点1到点n的最短路必然经过这个点的前驱和后继.相对的,有x方向的前驱后继,y方向的前驱后继
因此需要按照x,y排序,之后对每个点的对应的前驱后继连边,权重就参照距离算法.
然后最多有4n条边,再用spfa求解.
代码如下
#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f3f
struct node
{
int id;
int st,len;
};
vector<node>v;
queue<int>q;
int n,m,x;
bool cmp(node a,node b)
{
return a.st<b.st;
}
bool cmp2(node a,node b)
{
return a.id<b.id;
}
int checkst(int need)
{
int lastst=0,lastlen=0;
int temp;
int minkongst=inf;
for(int i=0; i<v.size(); i++) //先看空挡够不够
{
//cout<<v[i].st<<endl;
temp = v[i].st-lastst-lastlen;//空挡长度
//cout<<"temp:"<<temp<<endl;
if(temp>0)
{
minkongst = min(minkongst,lastst+lastlen);
}
if(temp>=need)
{
return lastst+lastlen;
}
lastst = v[i].st;
lastlen=v[i].len;
}
//按时间顺序删除
int deleteid = q.front();
q.pop();
vector<node>::iterator iter;
for(iter=v.begin(); iter!=v.end(); iter++) //再从第一个开始替换
{
if((*iter).id==deleteid)
v.erase(iter);
}
return -1;
}
int main()
{
//freopen("1.txt","r",stdin);
node add;
cin>>n>>m;
add.len=0;
add.st=m;
add.id=-1;
v.push_back(add);
for(int i=1; i<=n; i++)
{
q.push(i);
cin>>x;
add.len=x;
add.id=i;
add.st=checkst(x);
while(add.st==-1){
add.st=checkst(x);
}
v.push_back(add);
sort(v.begin(),v.end(),cmp);
// for(int j=0;j<v.size();j++)
// cout<<v[j].st<<"-"<<v[j].id<<" " ;
// cout<<endl;
}
sort(v.begin(),v.end(),cmp2);
for(int i=0; i<v.size(); i++)
{
if(v[i].id==-1)continue;
cout<<v[i].id<<" "<<v[i].st<<endl;
}
return 0;
}