POJ 3259
//题目类型:SPFA(邻接表实现)
//变量名字一定注意不要重复,因为此wa了n次。
#include <vector>
#include <queue>
//#include <conio.h>
#include <iostream>
using namespace std;
#define arraysize 501
int n,m,wnum;
int maxData = 0x7fffffff;
typedef struct edge
{
int to;
int w;
}edge;
vector<edge> adjmap[arraysize]; //vector实现邻接表
int d[arraysize];
bool final[arraysize];
int cnt[arraysize]; //记录顶点入队列次数
bool SPFA(int s)
{
queue<int> myqueue;
int i,j;
for(i=0;i<n+1;++i)
{
d[i] = maxData;
}
memset(final,0,sizeof(final));
memset(cnt,0,sizeof(cnt));
d[s]=0; //源点的距离为0
final[s] = true;
cnt[s]++; //源点的入队列次数增加
myqueue.push(s);
int topint;
while(!myqueue.empty())
{
topint = myqueue.front();myqueue.pop();
final[topint] = false;
for(i=0;i<adjmap[topint].size();++i)
{
int to = adjmap[topint][i].to;
if(d[topint]<maxData && d[to]>d[topint]+ adjmap[topint][i].w)
{
d[to] = d[topint]+ adjmap[topint][i].w;
if(!final[to])
{
final[to] = true;
cnt[to]++;
if(cnt[to]>=n) //当一个点入队的次数>=n时就证明出现了负环。
return true;
myqueue.push(to);
}
}
}
}
return false;
}
int main()
{
//freopen("1.txt","r",stdin);
int f;
int i,j;
int s,e,w;
edge temp;
cin>>f;
while(f--)
{
cin>>n>>m>>wnum;
for(i=1;i<n+1;++i) //此处特别注意对邻接表清空
adjmap[i].clear();
for(i=0;i<m;++i) //双向
{
cin>>s>>e>>w;
temp.to = e;
temp.w = w;
adjmap[s].push_back(temp);
temp.to = s;
adjmap[e].push_back(temp);
}
for(i=0;i<wnum;++i) //虫洞是单向
{
cin>>s>>e>>w;
temp.to = e;
temp.w = -w;
adjmap[s].push_back(temp);
}
if(SPFA(1)) //存在负权回路
cout<<"YES"<<endl;
else //不存在负权回路
cout<<"NO"<<endl;
}
//getch();
return 0;
}