poj 3259 spfa + Bellman-Ford

来源:互联网 发布:java算法书籍推荐 知乎 编辑:程序博客网 时间:2024/06/03 19:28

题目链接:点击打开链接

题意:确定图中有无负圈

1 spfa 邻接矩阵实现

#include <iostream>#include <stdio.h>#include <algorithm>#include <string.h>#include <vector>#include <queue>using namespace std;const int maxe = 7000 , maxv= 515 , INF =1e9 ;struct Edge{int to , cost ;};vector <Edge> G[maxe] ;int dist[maxv] , n , used[maxv] , vis[maxv];bool spfa(int s){    fill(dist , dist + n +1 , INF) ;    fill(vis , vis +n + 1 , 0 ) ;    fill(used , used + n +1, 0 ) ;    dist[s] = 0 ;    queue<int> que ;    que.push(s) ; vis[s] = 1 ; used[s] ++ ;    while(!que.empty())    {        int x = que.front() ; que.pop() ; vis[x] = 0 ;        for(int i = 0 ; i < G[x].size() ; i ++)        {            Edge e = G[x][i] ;            if(dist[e.to] > dist[x] + e.cost)            {                dist[e.to] = dist[x] + e.cost ;                if(!vis[e.to])                {                    vis[e.to] = 1 ;                  if(++used[e.to] > n - 1) return false ;                    que.push(e.to) ;                }            }        }    } return true ;}int main(){    //freopen("a.txt" , "r" , stdin ) ;    int t , m , W , u ,v, w ;    Edge edge ;    scanf("%d" , &t) ;    for(int ca = 1 ; ca <= t ; ca ++)    {        scanf("%d%d%d" , &n , &m, &W) ;        for(int i = 1 ; i <= n ; i ++) G[i].clear() ;        for(int i = 1 ; i <= m ; i ++)        {            scanf("%d%d%d" , &u , &v ,&w) ;            edge.to = v , edge.cost = w ;            G[u].push_back(edge) ;            edge.to = u ;            G[v].push_back(edge) ;        }        for(int i = 1 ; i <= W ; i ++)        {            scanf("%d%d%d" , &u, &v , &w) ;             edge.to = v , edge.cost = -w ;             G[u].push_back(edge) ;        }        if(!spfa(1)) printf("YES\n") ;        else printf("NO\n") ;    }    return 0;}

2 spfa 链式前向星

#include <iostream>#include <stdio.h>#include <algorithm>#include <string.h>#include <vector>#include <queue>using namespace std;const int maxe = 7000 , maxv= 515 , INF =1e9 ;struct Edge{int to , cost , next;}edge[maxe];int top , n , used[maxv] , vis[maxv] , head[maxv] , dist[maxv] ;void add_edge(int u , int v , int w){    edge[top].to = v ;    edge[top].cost = w ;    edge[top].next = head[u] ;    head[u] = top ++ ;}bool spfa(int s){    fill(dist , dist + n + 1 , INF) ;    fill(vis , vis + n + 1 , 0 ) ;    fill(used , used + n + 1 , 0) ;    queue<int > que ;    dist[s] = 0 ; used[s] ++ ; vis[s] = 1 ;    que.push(s) ;    while(!que.empty())    {        int u = que.front() ; que.pop() ; vis[u] = 0 ;        for(int i = head[u] ; i!= -1 ; i = edge[i].next)        {            Edge e = edge[i] ;            if(dist[e.to] > dist[u] + e.cost)            {                dist[e.to] = dist[u] + e.cost ;                if(!vis[e.to])                {                    vis[e.to] = 1 ;                    if(++used[e.to] > n - 1) return false ;                    que.push(e.to) ;                }            }        }    }    return true ;}int main(){    //freopen("a.txt" , "r" , stdin ) ;    int t , m , w , u , v , cost ;    scanf("%d" , &t) ;    while(t--)    {        scanf("%d%d%d" , &n , &m , &w) ;        for(int i = 1 ; i <= n ; i ++) head[i] = -1 ;        top = 0 ;        for(int i = 1 ; i <= m ; i ++)        {            scanf("%d%d%d" , &u , &v , &cost) ;            add_edge(u , v , cost) ;            add_edge(v , u , cost) ;        }        for(int i = 1 ; i <= w ; i ++)        {            scanf("%d%d%d" , &u , &v , &cost) ;            add_edge(u , v , -cost) ;        }        if(!spfa(1)) printf("YES\n") ;        else printf("NO\n") ;    }    return 0 ;}

3 Bellmon-Ford

#include <iostream>#include <stdio.h>#include <algorithm>#include <string.h>#include <vector>#include <queue>using namespace std;const int maxe = 7000 , maxv= 515 , INF =1e9 ;struct Edge{int to , cost , from;}edge[maxe];int dist[maxv] , n , top ;void add_edge(int u , int v  , int w){    edge[top].from = u ;    edge[top].to = v ;    edge[top++].cost = w ;}bool find_negative_loop(){    memset(dist , sizeof(dist) , 0) ;    for(int i = 0 ; i < n ; i ++)    {        for(int j = 0 ; j < top ; j ++)        {            Edge es = edge[j] ;            if(dist[es.to]  > dist[es.from] + es.cost)            {                dist[es.to] =  dist[es.from] + es.cost ;                if(i == n - 1 ) return true ;            }        }    }    return false ;}int main(){    //freopen("a.txt" , "r" , stdin ) ;    int t ,  m , w , from , to , cost ;    scanf("%d" , &t) ;    while(t --)    {        scanf("%d%d%d" , &n , &m , &w) ;        top = 0 ;  // 注意初始化        for(int i = 1 ; i <= m ; i ++ )        {            scanf("%d%d%d" , &from , &to , &cost) ;            add_edge(from , to , cost) ;            add_edge(to , from , cost ) ;        }        for(int i = 1 ; i <= w ; i ++ )        {            scanf("%d%d%d" , &from , &to , &cost) ;            add_edge(from , to , -cost) ;        }        if(find_negative_loop()) printf("YES\n") ;        else printf("NO\n") ;    }    return 0 ;}


0 0