zoukankan      html  css  js  c++  java
  • 最短路相关题目

    1.luoguP1807 最长路_NOI导刊2010提高(07)

    直通

    思路:

      求最长路,其实跟最短路是一毛一样的,跑一边spfa就好。我们只需要加点小优化:在存边的时候把w存为-w,然后最后输出的时候输出-dis[n]就好

    坑点:

      这是一个有向图,不是无向图

    上代码:

    #include <iostream>
    #include <cstdio>
    #include <queue>
    #include <cstring>
    using namespace std;
    
    const int N = 1501;
    const int M = 50001;
    int n,m;
    struct node {
        int next,to,w;
    } e[M<<1];
    int top,head[N];
    void add(int u,int v,int w) {
        top++;
        e[top].to=v;
        e[top].w=w;
        e[top].next=head[u];
        head[u]=top;
    }
    
    queue<int>q;
    int dis[N];
    bool flag,vis[N];
    void spfa() {
        memset(dis,0x7f,sizeof(dis));
        q.push(1);
        vis[1]=true;
        dis[1]=0;
        while(!q.empty()) {
            int u=q.front();
            q.pop();
            vis[u]=false;
            for(int i=head[u],v,w; i; i=e[i].next) {
                v=e[i].to,w=e[i].w;
                if(dis[u]+w<dis[v]) {
                    dis[v]=dis[u]+w;
                    if(!vis[v]) {
                        vis[v]=true;
                        q.push(v);
                    }
                    if(v==n) flag=true;
                }
            }
        }
    }
    
    int main() {
        scanf("%d%d",&n,&m);
        for(int i=1,u,v,w; i<=m; i++) {
            scanf("%d%d%d",&u,&v,&w);
            add(u,v,-w);
        }
        spfa();
        if(!flag) printf("-1");
        else printf("%d",-dis[n]);
        return 0;
    }
    View Code

    2.P1119 灾后重建

    直通

    思路:

      出题人超良心的帮我们把询问按时间顺序排序了,那我们就不需要vis数组记录每个点是否已经做过Floyd,只要每次读入的时候把之前的时间没处理过的全部处理一遍就可以。

    坑点:

      注意该题的初始化!其实要说的话应该是注意所有的Floyd的初始化,因为我们要用到dis[i][k]+dis[k][j],所以如果memset0x7f的话会有可能炸出负数来,那样的话Floyd就不准了,所以我们在进行初始化的时候最好是要初始化(memset)为0x3f才可以

    上代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath> 
    #define INF 0x3f3f3f3f
    using namespace std;
    
    const int M = 50015;
    const int N = 233;
    int n,m,Q,k;
    int dis[N][N],t[M];
    
    int main() {
        scanf("%d%d",&n,&m);
        memset(t,0x3f,sizeof(t));
        memset(dis,0x3f,sizeof(dis));
        for(int i=0; i<n; i++) scanf("%d",&t[i]),dis[i][i]=0;
        for(int i=1,u,v,w; i<=m; i++) {
            scanf("%d%d%d",&u,&v,&w);
            dis[u][v]=dis[v][u]=w;
        }
        scanf("%d",&Q);
        for(int x=1,u,v,c; x<=Q; x++) {
            scanf("%d%d%d",&u,&v,&c);
            //注意这里的k是不需要进行清零的,具体原因嘛,那就是因为良心的出题人啦 
            while(t[k]<=c) {
                for(int i=0; i<n; i++)
                    for(int j=0; j<n; j++)
                        dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
                k++;
            }
            //宏定义的INF就等价于memset的数 
            //所以dis[u][v]==INF就说明两点之间并没有进行联通
            //而t[u]以及t[v] >c则是端点并没有建好的情况 
            if(dis[u][v]==INF || t[u]>c || t[v]>c) printf("-1
    ");
            else printf("%d
    ",dis[u][v]);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    tail命令语法
    正则表达式示例
    HTTP状态码对照表 HTTP response codes
    linux 源的配置更新
    shell基本语法
    谁偷走了程序员的时间??
    Spring Data JPA 简单查询-接口方法
    GET和POST两种基本请求方法的区别
    您是怎样度过人生的低潮期的
    树莓派中Docker部署.Net Core 3.1 (一)
  • 原文地址:https://www.cnblogs.com/zxqxwnngztxx/p/7783804.html
Copyright © 2011-2022 走看看