洛谷 P3385 【模板】负环
一开始没注意到他的边是非负就是双向的。所以一直wa……
用SPFA。bfs判断是否有一个点进入次数超过n即可。
#include <algorithm> #include<iostream> #include<cstdio> #include<cstring> #include<vector> #include<queue> #define MAXN 2005 using namespace std; typedef pair<int,int> pii; queue<int>q;//pii的第一个值代表距离,第二个值代表点。根据距离排序 .注意两个> >之间要加空格否则会被认为是移位 int t,n,m,s,temp1,temp2,temp3,dis[MAXN],vis[MAXN],cnt[MAXN]; vector<pii>map1[MAXN];//pii的第一个值为连的点,第二个值为到该点的距离。 int spfa(int s){ memset(dis,0x3f3f3f3f,sizeof(dis)); memset(vis,0,sizeof(vis)); memset(cnt,0,sizeof(cnt)); while(!q.empty()) q.pop(); dis[s]=0; vis[s]=1; q.push(s); while(!q.empty()){ int u=q.front(); q.pop(); vis[u]=0; for(int i=0;i<map1[u].size();i++){ int v=map1[u][i].first; int w=map1[u][i].second; if(dis[v]>dis[u]+w){ dis[v]=dis[u]+w; if(!vis[v]){ q.push(v); vis[v]=1; cnt[v]=cnt[u]+1;//cnt[v]++也没有问题,但这个快很多 if(cnt[v]>=n) return 1; } } } } return 0; } int main(){ scanf("%d",&t); while(t--){ scanf("%d%d",&n,&m); for(int i=0;i<m;i++){ scanf("%d%d%d",&temp1,&temp2,&temp3); map1[temp1].push_back(make_pair(temp2,temp3)); if(temp3>=0)//非负则双向 map1[temp2].push_back(make_pair(temp1,temp3)); } if(spfa(1)) printf("YES\n"); else printf("NO\n"); for(int i=1;i<=n;i++) map1[i].clear(); } return 0; }

浙公网安备 33010602011771号