uva558

题目大意:
n个点,m条边,边给出的信息为:两个端点编号,以及权值,权值可为负数。判断图中是否存在负环。

思路:
bellmanford判断负环
spaf bfs判断负环

代码:
SPFA:

#include <iostream>
using namespace std;
#include <stdio.h>
#include <cstring>
#include <queue>
#define N 40000
#define M 100000
#define INF 0x3f3f3f3f

struct node {
    int v,w,n;
}edge[M];
int head[N],dis[N],cnt[N],n,m,s,f,num;
int vis[N];

void add(int a,int b,int c) {
    edge[num].v = b;
    edge[num].w = c;
    edge[num].n = head[a];
    head[a] = num++;
}

void SPFA() {
    for(int i = 0; i < n; i++) {
        dis[i] = INF;
        vis[i] = 0;
    }
    dis[s] = 0;
    vis[s] = 1;
    queue<int> Q;
    Q.push(s);
    while(!Q.empty()) {
        int u = Q.front();
        Q.pop();
        vis[u] = 0;
        for(int i = head[u]; i != -1; i = edge[i].n) {
            int v = edge[i].v;
            if(dis[v] > dis[u] + edge[i].w) {
                dis[v] = dis[u] + edge[i].w;
                if(!vis[v]) {
                    cnt[v] ++;
                    if(cnt[v] > n) {
                        f = 1;
                        return;
                    }
                    vis[v] = 1;
                    Q.push(v);
                }
            }
        }
    }
}
int main() {

    int T;
    int u,v,w;
    scanf("%d",&T);
    while(T--) {
        s = 0;
    // t = n - 1;
        memset(head,-1,sizeof(head));
        memset(cnt,0,sizeof(cnt));
        f = 0;
        num = 0 ;
    // cout << endl;
        scanf("%d%d",&n,&m);
        for(int i = 0; i < m; i++) {
            scanf("%d%d%d",&u,&v,&w);
            add(u,v,w);
        }
        //cout << endl;
        SPFA();
        if(f) 
            printf("possible\n");
        else
            printf("not possible\n");
    }
    return 0;
}

bellmanford算法:

#include <iostream>
using namespace std;
#include <cstring>
#include <stdio.h>
#include <algorithm>

const int maxn = 1005;
const int maxm = 2005;
struct edge {
    int u,v;
    int d;
}e[maxm];
const int INF =  0x3f3f3f3f;
int N,M;
int d[maxn];

bool BellmanFord() {
    //int flag = 0;
    for(int i = 0; i < N; i++) {
        d[i] = INF;
    }
    d[0] = 0;
    for(int i = 0; i < N - 1; i++)
        for(int j = 0; j < M; j++)
            if(d[e[j].u] != INF && d[e[j].v] > d[e[j].u] + e[j].d)
                d[e[j].v] = d[e[j].u] + e[j].d;
    for(int i = 0; i < M; i++)
        if(d[e[i].u]!= INF && d[e[i].u] + e[i].d < d[e[i].v])// {
            return true;
    /* flag = 1; d[e[i].v] = d[e[i].u] + e[i].d; break;*/
        //}
    /*if(flag) return false; return true;*/
    return false;
}
int main() {

    int T;
    scanf("%d",&T);
    while(T--) {
        scanf("%d%d",&N,&M);
        for(int i = 0; i < M; i++)
            scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].d);
        if(BellmanFord())
            printf("possible\n");
        else
            printf("not possible\n");
    }
    return 0;
}

你可能感兴趣的:(uva558)