题目大意&&思路:农夫玩穿越,找负环经典问题,
思路一:SPFA轻松撸过:原理:某一个节点入队n次的话则存在负环。(200ms)
思路二:Bellman-floyd 也OK:http://blog.youkuaiyun.com/kg_second/article/details/7888273 (其实在这道题思路二更快125ms,SPFA在数据大的时候才霸气尽出)
AC program:
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<queue>
#include<algorithm>
using namespace std;
#define inf 1000000000
#define maxn 10000
int visited[maxn],dis[maxn],st[maxn];
int ff[505];
int n,m,h;
int num;
int yes;
struct node
{
int x;
int value;
int next;
}e[maxn];
void init()
{
int u,v,w;
memset(st,0,sizeof(st));
memset(e,0,sizeof(e)); ///
int num=1;
cin>>n>>m>>h;
for(int i=1;i<=m;i++)
{
cin>>u>>v>>w;
e[num].x=v;
e[num].value=w;
e[num].next=st[u];
st[u]=num;
num++;
e[num].x=u;
e[num].value=w;
e[num].next=st[v];
st[v]=num;
num++;
}
for(int i=1;i<=h;i++)
{
cin>>u>>v>>w;
e[num].x=v;
e[num].value=-w; //negetive
e[num].next=st[u];
st[u]=num;
num++;
}
}
void init2()
{
memset(ff,0,sizeof(ff)); //判断节点出队的次数的数组
}
void spfa()
{
for(int i=1;i<=n;i++)
{
visited[i]=0;
dis[i]=inf;
}
visited[1]=1;
dis[1]=0;
queue<int>que;
que.push(1);
ff[1]++; //note
int tmp=st[1];
int cur;
int k=0;
while(!que.empty())
{
cur=que.front();
tmp=st[cur];
que.pop();
visited[cur]=0;
while(tmp!=0)
{
if(dis[e[tmp].x]>dis[cur]+e[tmp].value)
{
dis[e[tmp].x]=dis[cur]+e[tmp].value; ///
if(visited[e[tmp].x]==0) ///
{
que.push(e[tmp].x); ///
ff[e[tmp].x]++; //note2
if(ff[e[tmp].x]>=n)
{ yes=1; goto end; }
visited[e[tmp].x]=1;
}
}
tmp=e[tmp].next;
}
}
end:
if(yes==1)
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
}
int main()
{
int test;
cin>>test;
while(test--)
{
init();
init2();
yes=0; //判断变量
spfa();
}
//system("pause");
return 0;}