要求:n个点,m条正权无向边,w条负权有向边,问是否存在一个点i,从i出发又回到i的路径的权值为负。
方法:floyd
1.floyd裸题。
2.每次运算的时候要判断是否出现了负权环。
3.min函数没有手写的if快。
4.有重边,还是任何图论题多写一句判断重边为妙。
#include<iostream>
#include<stdio.h>
#include<queue>
#include<map>
#include<string.h>
#include<math.h>
#include<algorithm>
#define inf 0x3f3f3f3f
using namespace std ;
int n , m , w ;
int map1[505][505] ;
void floyd()
{
int i , j , k ;
for(i = 1 ; i <= n ; i ++)
for(j = 1 ; j <= n ; j ++)
{
for(k = 1 ; k <= n ; k ++)
//if(map1[j][i] != inf && map1[i][k] != inf)
if(map1[j][i] + map1[i][k] < map1[j][k])
map1[j][k] = map1[j][i] + map1[i][k] ;
if(map1[i][i] < 0)
{
printf("YES\n") ;
return ;
}
}
printf("NO\n") ;
}
int main()
{
int i , j , k , f ;
int s , e , t ;
scanf("%d" , &f) ;
while(f --)
{
scanf("%d%d%d" , &n , &m , &w) ;
memset(map1 , inf , sizeof(map1)) ;
for(i = 0 ; i < m ; i ++)
{
scanf("%d%d%d" , &s , &e , &t) ;
if(t < map1[s][e])
map1[s][e] = map1[e][s] = t ;
}
for(i = 0 ; i < w ; i ++)
{
scanf("%d%d%d" , &s , &e , &t) ;
map1[s][e] = -t ;
}
floyd() ;
}
}