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
  • 相关阅读:
    Two strings CodeForces
    Dasha and Photos CodeForces
    Largest Beautiful Number CodeForces
    Timetable CodeForces
    Financiers Game CodeForces
    AC日记——整理药名 openjudge 1.7 15
    AC日记——大小写字母互换 openjudge 1.7 14
    AC日记——将字符串中的小写字母换成大写字母 openjudge 1.7 13
    AC日记——加密的病历单 openjudge 1.7 12
    AC日记——潜伏着 openjudge 1.7 11
  • 原文地址:https://www.cnblogs.com/zxqxwnngztxx/p/7783804.html
Copyright © 2011-2022 走看看