关闭

spfa poj 3259

193人阅读 评论(0) 收藏 举报

题意:一个图,有一些“正常”的点和边(废话),点表示农场的位置、边表示从一个农场到另一个农场花费的时间。打住。还有些特别的点(虫洞),这些特别的点和其他点的边代表着能“穿越”的时间。问:有没有可能从虫洞穿越到某个点,时间倒流。

这个模型就是把正常的点互相连接起来或者把正常的点到虫洞,权是正。但是虫洞到其他的点,权为负。建立一个存在负权的图,然后最最最最关键的就是:判断是否存在负权回路。单源最短路算法里面正好bellman-ford可以处理负权,而且算法的返回值就是一个bool型的量,用来反映是不是存在负权回路了

/*
Sample Input

2
3 3 1
1 2 2
1 3 4
2 3 1
3 1 3
3 2 1
1 2 3
2 3 4
3 1 8
Sample Output

NO
YES

*/
#include<cstdio>
#include<vector>
#include<queue>
#include<cstring>

#define MAXVN 520
#define MAXEN 6000
#define INF 1000000000

using namespace std;

int dis[MAXVN], ispushed[MAXVN], pushtimes[MAXVN];

typedef struct{
    int v, value;
}Edge;
int vn, en;

typedef vector<Edge> VE;
VE eg[MAXVN];

queue<int>  Q;

int spfa(int st){
    memset(ispushed, 0, sizeof(ispushed));
    memset(pushtimes, 0, sizeof(pushtimes));
    for(int i = 1;i <= vn; i++)   dis[i] = INF;
    dis[st] = 0;
    while(!Q.empty()) Q.pop();
    Q.push(st); ispushed[st] = 1;
    pushtimes[st]++;
    while(!Q.empty()){
        int be = Q.front();
        Q.pop(); ispushed[be] = 0;
        for(int i = 0; i < eg[be].size(); i++){
            if(dis[eg[be][i].v] > dis[be] + eg[be][i].value){
                dis[eg[be][i].v] = dis[be] + eg[be][i].value;
                if(!ispushed[eg[be][i].v]){
                    Q.push(eg[be][i].v);
                    ispushed[eg[be][i].v] = 1;
                    pushtimes[eg[be][i].v]++;
                    if(pushtimes[eg[be][i].v] >= vn+1)  return 1;
                }
            }
        }
    }

    return 0;
}

int main(){
    int t, n, m, w,a, b, c;
    while(scanf("%d", &t) != EOF){
        while(t--){
            for(int i = 1; i <= vn; i++) eg[i].clear();
            scanf("%d%d%d", &n, &m ,&w);
            vn  =  n;
            while(m--){
                scanf("%d%d%d", &a, &b, &c);
                Edge tmp;
                tmp.v = b;
                tmp.value = c;
                eg[a].push_back(tmp);
                tmp.v = a;
                eg[b].push_back(tmp);

            }
            while(w--){
                scanf("%d%d%d", &a, &b, &c);
                Edge tmp;
                tmp.v = b;
                tmp.value = 0 - c;
                eg[a].push_back(tmp);
            }
            if(spfa(1)) printf("YES\n");
            else printf("NO\n");
        }
    }
}


0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:102566次
    • 积分:1837
    • 等级:
    • 排名:千里之外
    • 原创:99篇
    • 转载:12篇
    • 译文:0篇
    • 评论:6条
    最新评论