题目:http://poj.org/problem?id=3259
题意:判断n个顶点组成的有向图是否存在负回路。
分析:我是用spfa算法判断是否存在负权值回路,原理:如果存在负权值回路,某些顶点入队列将超过n次,因此只需添加一个数组统计每个顶点入队列的次数。
代码:
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int inf=99999999;
int head[10000],to[10000],next[10000],val[10000];
int u,v,w,n,id;
int vis[505],cnt[505],d[505];
void addedge(int u,int v,int w)
{
to[id]=v;
val[id]=w;
next[id]=head[u];
head[u]=id++;
}
int spfa()
{
int i;
memset(cnt,0,sizeof(cnt));
memset(vis,0,sizeof(vis));
for(i=2;i<=n;i++)
d[i]=inf;
d[1]=0;
queue<int> q;
q.push(1);
vis[1]=1,cnt[1]++;
while(!q.empty())
{
int u=q.front();
q.pop();
vis[u]=0;
for(i=head[u];i!=-1;i=next[i])
{
if(d[u]+val[i]<d[to[i]])
{
d[to[i]]=d[u]+val[i];
if(!vis[to[i]])
{
vis[to[i]]=1;
q.push(to[i]);
if(++cnt[to[i]]>n)
return 0;
}
}
}
}
return 1;
}
int main()
{
int t,m,c;
scanf("%d",&t);
while(t--)
{
scanf("%d%d%d",&n,&m,&c);
memset(head,-1,sizeof(head));
id=0;
while(m--)
{
scanf("%d%d%d",&u,&v,&w);
addedge(u,v,w);
addedge(v,u,w);
}
while(c--)
{
scanf("%d%d%d",&u,&v,&w);
addedge(u,v,-w);
}
if(spfa())
printf("NO\n");
else
printf("YES\n");
}
return 0;
}