训练日记2019.10.20 ACM/ICPC北美资格赛I题Slow Leak最短路

2019.10.20 星期日
今天整个就不想学啦,主要是codeforces打不动了,卡在div3上不去,真的头大了今天,我不该暂停训练的,可我有什么办法呢?

上上周的北美资格赛的I题,就是我连WA了20多发的那道题,今天居然写出来,原因让我很无语,就是爆int了,当时想了半天没想到这点,今天在休闲debug的时候意外发现自己增加常数可以多过一两个case,然后索性换了long long, 结果一发入魂?我今天在图书馆直接骂出来了,有了这道题我们该是第一啊!!!!之前怀疑过自己的算法,怀疑过出题人,就是没怀疑过爆int,饿,当时比赛的时候认为两个floyd矩阵已经挤占了较大空间,然后就没有往longlong上想了,结果给我来了这一出,真是防不胜防!!!!难受也没用,当时要是想到这点就绝杀了,可惜啊,可惜,哎,明年不会比今年差的,codeforces打上去再说!!

下面出题解

题目: ICPC北美预选赛I题Slow Leak(传送门)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
大多数人没法科学上网,我就借助地理优势给搬过来了,大意是车轮胎破了,然后骑车从1到n,m条路,每次骑车不能超过maxDist这个距离,轮胎的气可以在中间的q个维修站补足。

很好,当时比赛的想法就是dijkstra做深搜,然后每到一个点就开始减去可以骑车的距离,如果车在中途没气了(dist <= 0), 那么就剪枝进行下一条路的搜索。这样做的确可以,不过之后想到了一个更好的办法,那就是二维数组连边,然后跑一遍floyd多源最短路,最后只把加油站的点和起始点连起来,做dijkstra求最短路从1到n就行了。可惜了,没能及时找出爆int这个问题,大家看看吧。
下面放ac题解,我是用dijkstra做的,虽然这道题数据量很小(500)而且给足了时间,但是我觉得两遍floyd还是会挤占大量的时空内存,所以还是跑了一遍dijkstra。记得INF要开大,常用的0x3f3f3f3f是不行的
AC代码:

#include <bits/stdc++.h>
using namespace std;
#define limit 3000 + 5//防止溢出
#define INF 0x3f3f3f3f3f
#define inf 1<<20
#define lowbit(i) i&(-i)//一步两步
#define EPS 1e-6
#define ff(a) printf("%d\n",a );
#define MOD 1e9 + 7
typedef long long ll;
void read(int &x){
    char ch = getchar();x = 0;
    for (; ch < '0' || ch > '9'; ch = getchar());
    for (; ch >='0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';
}//快读
int  n , m , sta, k;
int vis[limit];
ll first[limit][limit];
struct edge{
    int to;
    ll weight;
    edge(int tt = 0 , ll w = 0): to(tt), weight(w){}
    bool operator<(const edge &rhs)const{
        return weight > rhs.weight;
    }
};
vector<vector<edge> >v;
int visited[limit];
ll dijkstra(){
    edge u(1,0);
    priority_queue<edge>q;
    q.push(u);
    int flag = 0;
    for(int i = 0 ; i <= n ; ++i){
        visited[i] = 0;
    }
    while(q.size()){
        u = q.top();
        q.pop();
        if(visited[u.to])continue;
        visited[u.to] = 1;
        if(u.to == n){
            flag = 1;
            break;
        }
        for(int i = 0 ; i < v[u.to].size() ; ++i){
            edge tmp = v[u.to][i];
            if(visited[tmp.to])continue;
            tmp.weight += u.weight;
            q.push(tmp);
        }
    }
    return flag ? u.weight : INF;
}
int main(){
    //freopen("C:\\Users\\administrator01\\CLionProjects\\untitled14\\data.txt", "rt" , stdin);
    scanf("%d%d%d%d" , &n , &m , &sta, &k);
    for(int i = 1; i <= n ; ++i){
        vis[i] = 0;
        for(int j = 1 ; j <= n ; ++j){
            if(i == j){
                first[i][j] = 0;
            }else{
                first[i][j] = INF;
            }
        }
    }
    memset(vis, 0 , sizeof(vis));
    for(int i = 0 ; i < sta; ++i){
        int station;
        scanf("%d" , &station);
        vis[station] = 1;
    }
    for(int i = 0 ; i < m  ;++i){
        ll from , to , weight;
        scanf("%lld%lld%lld" , &from, &to, &weight);
        ll orig = first[from][to];
        ll orig2 = first[to][from];
        weight = min(orig, weight);
        weight = min(orig2 , weight);
        first[from][to] = first[to][from] = weight;
    }

    vis[1] = 1;
    vis[n] = 1;
    for(int k = 1; k <= n ; ++k){
        for(int i = 1 ; i <= n ; ++i){
            for(int j = 1 ; j <= n ; ++j){
                first[i][j] = min(first[i][j], first[i][k] + first[k][j]);
            }
        }
    }
    v.resize(n + 1);
    for(int i = 1 ; i <= n ; ++i){
        for(int j = 1; j <= n ; ++j){
            if(vis[i] && vis[j] && first[i][j] <= k && i != j){
                v[i].push_back(edge(j, first[i][j]));
                //v[j].push_back(edge(i, first[i][j]));
            }
        }
    }
    ll ans = dijkstra();
    if(ans == INF){
        printf("stuck");
    }else{
        printf("%lld", ans);
    }
    return 0;
};
发布了69 篇原创文章 · 获赞 1 · 访问量 3042

猜你喜欢

转载自blog.csdn.net/Stagflation/article/details/102656577