有n个农场,m条路径,w条虫洞路径。 随后输入m条路径,要处理双向边。然后跟w条虫洞路径,输入这个路径值时要取反。构图然后spfa判环。 #include <iostream> #include <vector> #include <queue> using namespace std; /* 传入源点s,n存储点的个数,用dis数组存下最短路径值 edge[i]存入与i相邻的点及其权值 返回值为true则无负环,为false则存在负环 */ class node { public: int v,w; }; const int inf=0x7fffffff; const int MAXN=600; int numv,dis[MAXN]; bool visit[MAXN]; int time[MAXN],n,m,w; vector<node> edge[MAXN]; bool spfa(int s) { int tmp,t,sz; queue<int> que; memset(time,0,sizeof(time)); memset(visit,false,sizeof(visit)); for(int i=0;i<=n;++i) dis[i] = inf; dis[s] = 0; que.push(s); time[s]++; //init while(!que.empty()) { tmp = que.front(); que.pop(); visit[tmp] = false; sz=edge[tmp].size(); for(int i=0;i<sz;++i) { t = edge[tmp][i].w; if(dis[edge[tmp][i].v] > dis[tmp]+t) { dis[edge[tmp][i].v] = dis[tmp] + t; if(!visit[edge[tmp][i].v]) //若该点不在队列中,则入队,并修改相应的信息 { visit[edge[tmp][i].v] = true; time[edge[tmp][i].v]++; if(time[edge[tmp][i].v] > n) return false; //若一个点的引用次数大于n则证明有负环 que.push(edge[tmp][i].v); } } } if(dis[s]<0) //判负环 return false; } return true; } int main() { int cas,s,e,t; node tmp; cin>>cas; while(cas--) { cin>>n>>m>>w; for(int i=1;i<=n;++i) edge[i].clear(); while (m--) { cin>>s>>e>>t; tmp.v=e; tmp.w=t; edge[s].push_back(tmp); tmp.v=s; tmp.w=t; edge[e].push_back(tmp); //处理双向边 } while(w--) { cin>>s>>e>>t; tmp.v=e; tmp.w= -t; edge[s].push_back(tmp); } if(spfa(1)) cout<<"NO"<<endl; else cout<<"YES"<<endl; } return 0; }