dlut1219-spfa+二维dis

来源:互联网 发布:帝国cms怎么样 编辑:程序博客网 时间:2024/06/05 23:58

题目:

DDR Ddr
 
DDR口头禅:
我要征服地球!
 
星座:魔蝎座
生日:12月22日
血型:不明
年龄:不明
生肖:不明
身高:139公分
体重:37公斤
 
 
 
职业:不明
兴趣:看科幻电影
宠物:龟鸟(来自DR星的小生物)
最喜欢:开UFO飙飞
最讨厌:记者用闪光照相机给它拍照
偶像:ET外星人
语言:中文
 
 
 
来自DANCE RACING星球的外星人,看上去有点可爱有点邪恶的样子,来到地球的原因是因为飞行器出现,由于地球人不流通DR星的货币,所以他最大的希望是赚足够多的地球货币,用以修好飞船,为此他苦学人类的商业经济学知识,凭借超人的聪明,目前他所具备的商业头脑,就是20个哈佛高材生加在一起也比不上他。
 
平时喜欢躲在他那小小的UFO里通过星际超时空电脑网络和远在两万光年以外DR星的网友们聊天。虽然这是外星人头一次登陆大富翁的世界,千万别小看了它呀,据说有几个邪恶组织打算捉它去做试验,但最后都以失败告终。
 
科学怪人最近盯上了DDR,要拿他做实验。DDR在科学怪人找到他之前尽快逃离地球,并回到DR星。DDR的飞船是由电力提供动力的,飞船可以储存一定的电量,我们记可以存储的最大电量为C。宇宙中有多个星球,每个星球中都有充电站能免费给DDR的飞船充电,这样DDR就可以在中途停下来补充电能,然后继续前进。但是我们DDR的飞船每次启动时都要消耗一个特殊的燃料,这种燃料的缩写是AC。虽然每个星球都有充电站,但并不是每个星球都有AC燃料站的。DDR的飞船最大可以存储AC的量是S。每次DDR补充电量或者AC燃料的时候都可以直接充满,而且消耗的时间可以忽略不计。DDR的飞船不能中途没电。
 
现在我们给出一些详细数据:
宇宙每个星球的位置由一个三维坐标来标记(x,y,z),地球的位置是(0,0,0)
从位于(x1,y1,z1)位置的星球飞到位置在(x2,y2,z2)位置的星球
需要消耗的电量:|x1-x2|+|y1-y2|+|z1-z2|
需要消耗的时间是:(max(|x1-x2|,|y1-y2|,|z1-z2|)+min(|x1-x2|,|y1-y2|,|z1-z2|))/2,向上取整(x向上取整的意思是取不小于x的最大整数)
 
例如:从位于(0,0,0)飞到(1,0,0)需要的时间是1,需要消耗的电量是1
 
DDR在出发前的AC燃料和电量都是满的。现在DDR想知道,他逃回DR星需要的最小时间是多少?
 

Input

T<=10代表测试数据个数
N<=1000代表宇宙中其它星球的个数
然后N行,每行4个整数,x,y,z,H
-100<=x,y,z<=100代表该星球的坐标,H代表改星球有没有AC燃料站,1代表有,0代表没有
然后是0<=C<=100,1<=S<=5意义见题目描述
然后是三个整数-100<=tx,ty,tz<=100代表DR星的位置

Output

对每组测试数据输出DR需要的最小时间,每组输出占一行,如果DDR不能会回到DR星则输出-1

Sample Input

211 0 0 11 12 0 011 0 0 01 12 0 0

Sample Output

2-1



啊,不容易,在组长的提示下,在re和wa之间交错,我终于过了!

以电量来建边,以时间作为边权,这题的dis要用二维,第一维记录节点,第二维记录剩余次数;队列也要记录两个值:一为节点,二为剩余次数;之后找最小值的就可以了;

#include<cstdio>#include<iostream>#include<cstring>#include<queue>#include<cmath>using namespace std;const int maxn=1005;const int Maxn=2*1002*1002;const int INF=0x3f3f3f3f;struct edge{    int v,w;    int next;};edge side[Maxn];int head[maxn];int N;int top=0;void addEdge(int from,int to,int w){    side[top].v=to;side[top].w=w;    side[top].next=head[from];    head[from]=top++;}int ac[maxn];int x[maxn],y[maxn],z[maxn];int inqueue[maxn];int dis[maxn][10];int C,S;typedef pair<int ,int> Pair;int spfa(int from ,int to){    memset(dis,INF,sizeof(dis));    memset(inqueue,0,sizeof(inqueue));    dis[from][S]=0;    inqueue[from]=1;    queue<Pair> que;    que.push(Pair(from,S));    while(!que.empty()){        int x=que.front().first,acx=que.front().second;        que.pop();        inqueue[x]=0;        if(acx==0)continue;        for(int i=head[x];i!=-1;i=side[i].next){            int y=side[i].v;            int acy;            if(ac[y]==1) acy=S;            else acy=acx-1;            if(dis[y][acy]>dis[x][acx]+side[i].w){                dis[y][acy]=dis[x][acx]+side[i].w;                if(!inqueue[y]&&acy!=0){                    que.push(Pair(y,acy));                    inqueue[y]=1;                }            }        }    }    /*for(int i=0;i<=N+1;i++){        for(int j=0;j<=S;j++)            printf("%d(%d):%d\n",i,j,dis[i][j]);    }*/    int MIN=INF;    for(int i=0;i<=S;i++){        MIN=min(MIN,dis[N+1][i]);        //printf("%d:%d\n",i,dis[N+1][i]);    }    return MIN;}int main(){    //freopen ("int.txt","r",stdin);    int T;    scanf("%d",&T);    while(T--){        scanf("%d",&N);        memset(head,-1,sizeof(head));        x[0]=0;y[0]=0;z[0]=0;        for(int i=1;i<=N;i++){            scanf("%d%d%d%d",&x[i],&y[i],&z[i],&ac[i]);        }        scanf("%d%d",&C,&S);        scanf("%d%d%d",&x[N+1],&y[N+1],&z[N+1]);ac[N+1]=1;        top=0;        for(int i=0;i<=N+1;i++){            for(int j=1;j<=N+1;j++){                if(i!=j&&(abs(x[i]-x[j])+abs(y[i]-y[j])+abs(z[i]-z[j])<=C)){                    int time=(max(abs(x[i]-x[j]),max(abs(y[i]-y[j]),abs(z[i]-z[j])))+min(abs(x[i]-x[j]),min(abs(y[i]-y[j]),abs(z[i]-z[j])))+1)/2;                    //printf("%d->%d:time:%d\n",i,j,time);                    addEdge(i,j,time);                    addEdge(j,i,time);                }            }        }       /* for(int i=0;i<maxn;i++){            if(head[i]!=-1){                for(int x=head[i];x!=-1;x=side[x].next){                    int y=side[x].v,len=side[x].w;                    printf("%d->%d:%d\n",i,y,len);                }            }        }*/        int ans=spfa(0,N+1);        if(ans==INF)printf("-1\n");        else printf("%d\n",ans);    }    return 0;}


0 0
原创粉丝点击