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:\n",cnt++);

        spfa();
        while(q--){
            int x;
            scanf("%d",&x);
            if(circle[x] || d[x]==INF || d[x]<3){
                printf("?\n",d[x]);
            }
            else printf("%d\n",d[x]);
        }
    }

    return 0;
}

 

 

posted on 2018-10-08 20:31  Helpp  阅读(257)  评论(2编辑  收藏  举报

导航