本题可抽象为:给出一些点和边,边分为两种,一种为双向边,权值为正,一种为单向边,权值为负。要求给定一个图,判断图中是否有负环。很显然,需要Bellman-Ford算法。因为本题只需判断是否有负环的存在,而不需求最短路,所以可令初始dis均为0,如果第n次松弛成功,则有负环;否则没有。
//9043487 NKHelloWorld 3259 Accepted 452K 79MS G++ 1459B 2011-07-31 13:15:57 //1A #include <cstdio> #include <cstring> struct date { int st,ed,d; }edge[5300]; int n,m,w,dis[510],cases,edgenum; int main() { int i,k; scanf("%d",&cases); while(cases-- >0) { memset(dis,0,sizeof(dis)); edgenum = 0; scanf("%d%d%d",&n,&m,&w); for(i=1;i<=m;i++) { edgenum ++; scanf("%d%d%d",&edge[edgenum].st,&edge[edgenum].ed,&edge[edgenum].d); edgenum ++; edge[edgenum].st = edge[edgenum-1].ed; edge[edgenum].ed = edge[edgenum-1].st; edge[edgenum].d = edge[edgenum-1].d; } for(i=1;i<=w;i++) { edgenum ++; scanf("%d%d%d",&edge[edgenum].st,&edge[edgenum].ed,&edge[edgenum].d); edge[edgenum].d = 0 - edge[edgenum].d; } bool flag; for(k=1;k<=n;k++) { flag = true; for(i=1;i<=edgenum;i++) { if(dis[edge[i].ed] - edge[i].d > dis[edge[i].st]) { dis[edge[i].ed] = dis[edge[i].st] + edge[i].d; flag = false; } } if(flag) break; } if(k>n) printf("YES\n"); else printf("NO\n"); } return 0; }