题目链接:点击打开链接
题意:确定图中有无负圈
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 ;
}