本题可抽象为:给出一些点和边,边分为两种,一种为双向边,权值为正,一种为单向边,权值为负。要求给定一个图,判断图中是否有负环。很显然,需要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;
}
posted on 2011-07-31 14:07  NKHe!!oWor!d  阅读(255)  评论(0编辑  收藏  举报