本题可抽象为:给出一些点和边,边分为两种,一种为双向边,权值为正,一种为单向边,权值为负。要求给定一个图,判断图中是否有负环。很显然,需要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;
}
浙公网安备 33010602011771号