• Light oj 1074 spfa标记负环节点


    题意:

    对图中的N点,给出q个询问,输出起点到询问点之间的最短路.

    若不可达或最短路小于3,输出   ?  

     

    思路:如果图中存在负环,那么若询问负环中的点,都需要输出'?'.
    所以在spfa中要增加一个环节,当判断到存在负环时,需要用dfs标记出当前负环上的所有点.

    #include<cstdio>
    #include<iostream>
    #include<queue>
    #include<cstring>
    #include<cmath>
    using namespace std;
    
    #define ll long long
    #define pb push_back
    #define fi first
    #define se second
    #define pii pair<int,int>
    #define mp make_pair
    
    const int N = 3333;
    const int INF = 1E9+3;
    
    struct edge{
        int to,cost;
    };
    
    vector<edge> V[N];
    
    int b[N],d[N];
    int vis[N];
    int circle[N];
    int num[N];
    int n; int m;
    void dfs(int t){
        circle[t]=1;
        for(int i=0;i<V[t].size();++i){
            if(circle [ V[t][i].to ] ==0){
                dfs(V[t][i].to);
            }
        }
    
    }
    
    void spfa(){
        memset(vis,0,sizeof(vis));
        memset(circle,0,sizeof(circle));
        for(int i=1;i<=n;++i)d[i]=INF;
        d[1]=0;
        queue<int>Q;
        Q.push(1);
        vis[1]=1;
        num[1]=1;
        while(!Q.empty()){
    
            int v = Q.front();Q.pop();
            vis[v]=0;
            for(int i=0;i<V[v].size();++i){
                int u =V[v][i].to;int val  =V[v][i].cost;
                if(circle[u])continue;
                if(d[u] > d[v]+val){
                    d[u]=d[v]+val;
                    if(vis[u]==0){
                        vis[u]=1;
                        Q.push(u);
                        num[u]++;
                        if(num[u]>n)dfs(u);
                    }
                }
            }
    
        }
    }
    int main(){
    
        int t;
        cin>>t;
        int cnt =1;
    
        while(t--){
            scanf("%d",&n);
            for(int i=1;i<=n;++i)scanf("%d",b+i);
            for(int i=1;i<=n;++i)V[i].clear();
    
            scanf("%d",&m);
            int u,v;
            while(m--){
                scanf("%d %d",&u,&v);
                int d = b[v]-b[u];
                V[u].pb( edge{ v, d*d*d } );
            }
            int q;
            cin>>q;
            printf("Case %d:
    ",cnt++);
    
            spfa();
            while(q--){
                int x;
                scanf("%d",&x);
                if(circle[x] || d[x]==INF || d[x]<3){
                    printf("?
    ",d[x]);
                }
                else printf("%d
    ",d[x]);
            }
        }
    
        return 0;
    }

     

  • 相关阅读:
    华硕B360主板装机找不到固态硬盘启动
    Maxwell平滑升级流程
    快速导入Excel数据到mysql
    Docker
    Rest之路
    Rest之路
    Docker -- resolve "join node timeout" error
    (转) Docker
    Docker
    Docker
  • 原文地址:https://www.cnblogs.com/wjhstudy/p/9756958.html
Copyright © 2020-2023  润新知