poj1661 最短路

来源:互联网 发布:sql with as等价 编辑:程序博客网 时间:2024/05/22 13:30

相当机智的一题,原本是放在DP专题里的题,思路一开始不是很清晰

看了网上dp解法后,感觉并不是很写的来

接着我开始想是否能暴力过去

于是很自然想到要构图,跑最短路了

每一层平台的左端点和右端点各自当做图中一个点

与其下方能到达的平台的左右端点相连

边权是高度差+水平差

建边时n^2暴力,起始点为0号点,地面为2*n+1号点

注意初始点连出去的边要单独处理

到地面的边要单独处理

Trick:可能直接落下到地面,要特判

建完后跑一遍迪杰斯特拉


#include <cstdio>#include <algorithm>#include <cstring>#include <cstdlib>#include <iostream>#include <cassert>#include <sstream>#include <numeric>#include <climits>#include <string>#include <cctype>#include <ctime>#include <iomanip>#include <cmath>#include <vector>#include <queue>#include <list>#include <map>#include <set>using namespace std;struct data{int h,l,r;}p[1010];struct edge{int next,len,to;}bian[101000];struct node{int id,dis;};int T,n,X,Y,MAX;int size=0,first[100100];int dis[100010],exist[100010];bool operator <(node a,node b){return a.dis>b.dis;}bool comp(data x,data y){return x.h>y.h;}void add(int x,int y,int z){size++;bian[size].next=first[x];first[x]=size;bian[size].to=y;bian[size].len=z;}void dijkstra(int s,int t){priority_queue<node>q;dis[s]=0;q.push((node){s,0});while(!q.empty()){node t=q.top();q.pop();int u=t.id;if(exist[u])continue;exist[u]=1;dis[u]=t.dis;for(int i=first[u];i;i=bian[i].next){if(dis[bian[i].to]>dis[u]+bian[i].len){dis[bian[i].to]=dis[u]+bian[i].len;q.push((node){bian[i].to,dis[bian[i].to]});}}}printf("%d\n",dis[2*n+1]);}void addedge(){for(int i=1;i<=n;i++){int cnt1=0,cnt2=0;for(int j=i+1;j<=n;j++){if(p[i].h-p[j].h>=0&&p[i].h-p[j].h<=MAX)     {if(p[j].l<=p[i].l&&p[i].l<=p[j].r&&cnt1==0)     {cnt1++;int ldis=p[i].h-p[j].h+p[i].l-p[j].l;add(i*2-1,j*2-1,ldis);int rdis=p[i].h-p[j].h+p[j].r-p[i].l;add(i*2-1,j*2,rdis);}if(p[j].l<=p[i].r&&p[i].r<=p[j].r&&cnt2==0) {                    cnt2++;                    int ldis=p[i].h-p[j].h+p[i].r-p[j].l;                    add(i*2,j*2-1,ldis);                    int rdis=p[i].h-p[j].h+p[j].r-p[i].r;                    add(i*2,j*2,rdis);                }}}if(cnt1==0&&p[i].h<=MAX)add(i*2-1,2*n+1,p[i].h);if(cnt2==0&&p[i].h<=MAX)add(i*2,2*n+1,p[i].h);}int cnt=0;for(int i=1;i<=n;i++)    if(p[i].l<=X&&X<=p[i].r&&Y-p[i].h>=0&&Y-p[i].h<=MAX&&cnt==0) {        cnt++;        if(cnt==1) {            int ldis=Y-p[i].h+X-p[i].l;            add(0,i*2-1,ldis);            int rdis=Y-p[i].h+p[i].r-X;            add(0,i*2,rdis);        }    }    if(cnt==0)        add(0,2*n+1,Y);}void clear(){size=0;memset(first,0,sizeof(first));memset(dis,127,sizeof(dis));memset(exist,0,sizeof(exist));}int main(){//freopen("in.in","r",stdin);scanf("%d",&T);while(T--){clear();scanf("%d%d%d%d",&n,&X,&Y,&MAX);for(int i=1;i<=n;i++)scanf("%d%d%d",&p[i].l,&p[i].r,&p[i].h);sort(p+1,p+n+1,comp);addedge();dijkstra(0,2*n+1);}}


0 0
原创粉丝点击