搜狗2019秋招的一道算法题:龟兔赛跑

时间限制:3秒

空间限制:92160K

定义如下图所示的比赛地图:
 
S表示比赛起点,E表示比赛终点。实线表示陆路,虚线表示水路。兔子只能走陆路,乌龟既可以走陆路也可以走水路。每条路径的长度在图中给出。假定兔子和乌龟足够聪明,问谁先到达终点。

输入描述:
第1行输入v1,v2。v1是兔子的速度,v2是乌龟的速度(水路、陆路速度相同)。第2行输入n,m,点的编号是1~n,然后是m行,其中1是起点,n是终点(路径本身不限定方向)。下面m行4个数 a, b, d, c,表示a和b之间有一条边,且其长度为d,类型是c(0表示陆路,1表示水路)。最后一行是end,表示输入结束。输入保证1和n之间至少有一条路径联通。(1<n<=10000, 0<m<=1000000)。

输出描述:
输出-1,0,1中的一个数。-1表示乌龟获胜,1表示兔子获胜,0表示同时到达终点。

输入例子1:
10 5
3 3 
1 2 30 0
2 3 20 0
1 3 20 1
end

输出例子1:
-1

声明:这道题在牛客提交只过了90%的数据,拿到了45分,最后一个样例没过,思考了很久,认为都考虑到了,又看了下分数排名,我认为他们的最后一个比较大的case数据有问题。如果有人都过了case
也可以留下评论,我哪里写错了。
代码如下:
#include <stdio.h>
#include <string.h>
#include <stdio.h>
#include <algorithm>
#include <math.h>
#include <vector>
#define INF 2100000000

using namespace std;

int n, m;
struct node
{
    int point; //端点
    int weight; //路径长度
    bool worl; //是否水路
};
vector<node>amap[10010];
unsigned int dis[10010];
bool vis[10010];

int Dijkstra(bool torr)
{
    memset(vis, false, sizeof(vis));
    for(int i=1; i<=n; i++) {
        dis[i] = INF; //代表不可达
    }
    int len = amap[1].size();

    if(torr) {
        for(int i=0; i<len; i++) {
            if( amap[1][i].weight < dis[amap[1][i].point] )
                dis[amap[1][i].point] = amap[1][i].weight;
        }
    } else {
        for(int i=0; i<len; i++) {
            if( !amap[1][i].worl && amap[1][i].weight < dis[amap[1][i].point] )
                dis[amap[1][i].point] = amap[1][i].weight;
        }
    }

    vis[1] = true;

    for(int k=0; k<n-1; k++) {
        int pos, mdis = INF;

        for(int i=1; i<=n; i++) {
            if(!vis[i] && dis[i] < mdis) {
                mdis = dis[i]; pos = i;
            }
        }
        vis[pos] = true;
        len = amap[pos].size();

        if(torr == true) { // 乌龟的话,所有的dis都可以拿来更新
            for(int j=0; j<len; j++) {
                if( !vis[amap[pos][j].point] && dis[amap[pos][j].point] > (amap[pos][j].weight+dis[pos]) ) {
                    dis[ amap[pos][j].point ] = amap[pos][j].weight + dis[pos];
                }
            }
        } else { // 兔子的话,更新的可选路径必须是陆路
            for(int j=0; j<len ; j++) {
                if( !vis[amap[pos][j].point] && !amap[pos][j].worl && dis[amap[pos][j].point] > (amap[pos][j].weight+dis[pos]) )
                    dis[ amap[pos][j].point ] = amap[pos][j].weight + dis[pos];
            }
        }
    }
    return dis[n];
}

int main()
{
    double vt, vg;
    scanf("%lf %lf", &vt, &vg);
    scanf("%d %d", &n, &m);

    int a, b, c, d;
    node cur;
    for(int i=0; i<m; i++) {
        scanf("%d %d %d %d", &a, &b, &c, &d);
        cur.point = b;
        cur.weight = c;
        cur.worl = (d==1?true:false);
        amap[a].push_back(cur);
    }
    char str[100];
    scanf("%s", str);

    double tt = (double)Dijkstra(false) / vt; // tu zi
    double tg = (double)Dijkstra(true) / vg; // gui

    double eps = 1e-8;
    if(fabs(tt - tg) < eps) {
        printf("0\n");
    } else if(tt - tg > eps) {
        printf("-1\n");
    } else {
        printf("1\n");
    }
    return 0;
}

  

posted @ 2019-03-13 23:16  我喜欢旅行  阅读(508)  评论(0编辑  收藏  举报