解法:
思路很简单,只需判断图中是否含有负权回路即可。
SPFA算法:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
const int inf=0x3f3f3f3f;
const int Max_v=550;
struct edge{
int to,cost;
edge(int t,int c):to(t),cost(c){}
};
int N,M,W,F;
int dist[Max_v];
bool vis[Max_v];
int cnt[Max_v];
vector<edge>G[Max_v];
bool SPFA(int s){
memset(dist,0x3f,sizeof(dist));
memset(vis,0,sizeof(vis));
memset(cnt,0,sizeof(cnt));
queue<int>que;
que.push(s);
dist[s]=0;vis[s]=1;cnt[s]=1;
while(!que.empty()){
int u=que.front();que.pop();
vis[u]=0;
for(int i=0;i<G[u].size();i++){
edge e=G[u][i];
if(dist[e.to]>dist[u]+e.cost){
dist[e.to]=dist[u]+e.cost;
if(!vis[e.to]){
que.push(e.to);vis[e.to]=1;
//if(++cnt[e.to]>=N)return true; //判负环(思路一)
}
}
}
if(dist[s]<0)return true; //判负环(思路二,较快)
}
return false;
}
int main()
{
scanf("%d",&F);
while(F--){
scanf("%d%d%d",&N,&M,&W);
for(int i=0;i<=N;i++)G[i].clear();
int a,b,c;
for(int i=0;i<M;i++){
scanf("%d%d%d",&a,&b,&c);
G[a].push_back(edge(b,c));
G[b].push_back(edge(a,c));
}
for(int i=0;i<W;i++){
scanf("%d%d%d",&a,&b,&c);
G[a].push_back(edge(b,-c));
}
if(SPFA(1))printf("YES\n");
else printf("NO\n");
}
return 0;
}
Floyd算法:
- 2s勉勉强强能过,本来以为过不了,看了别的博客都过了,多次TLE之后发现min函数拖了后腿,why?
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int inf=0x3f3f3f3f;
const int Max_v=501;
int N,M,W,F;
int d[Max_v][Max_v];
bool Floyd(){
for(int k=1;k<=N;k++){
for(int i=1;i<=N;i++){
for(int j=1;j<=N;j++){
int t=d[i][k]+d[k][j];
if(d[i][j]>t)d[i][j]=t; // AC 1688MS
//d[i][j]=min(d[i][j],d[i][k]+d[k][j]) TLE(不知原因)
}
if(d[i][i]<0)return true;
}
}
return false;
}
int main()
{
scanf("%d",&F);
while(F--){
scanf("%d%d%d",&N,&M,&W);
memset(d,0x3f,sizeof(d));
for(int i=1;i<=N;i++)d[i][i]=0;
int a,b,c;
for(int i=0;i<M;i++){
scanf("%d%d%d",&a,&b,&c);
if(c<d[a][b]){
d[a][b]=c;d[b][a]=c;
}
}
for(int i=0;i<W;i++){
scanf("%d%d%d",&a,&b,&c);
d[a][b]=-c;
}
if(Floyd())printf("YES\n");
else printf("NO\n");
//for(int i=1;i<=N;i++)cout<<d[i][i]<<' ';
}
return 0;
}