http://poj.org/problem?id=3259
比较考英语的一道题。。。先有一组双向的边,还有一组单向的边,然后SPFA找负环,就判断一下有没有入队次数大于n的就行了。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
#define INF 0x3f3f3f3f3f
using namespace std;
struct Edge{
int w,v,next;
}e[1000010];
bool vis[1000010];
int k,n,m,w,F;
int head[1000010],sum[1000010],dis[1000010];
void addedge(int u,int v,int w)
{
e[k].v=v;
e[k].w=w;
e[k].next=head[u];
head[u]=k++;
}
bool spfa()
{
memset(vis,0,sizeof(vis));
memset(dis,0x3f,sizeof(dis));
memset(sum,0,sizeof(sum));
queue<int> q;
q.push(1);
dis[1]=0;
while(!q.empty())
{
int t=q.front();
q.pop();
vis[t]=0;
for(int i=head[t];i;i=e[i].next)
{
int v=e[i].v;
int w=e[i].w;
if(dis[v]>dis[t]+w)
{
dis[v]=dis[t]+w;
if(!vis[v])
{
q.push(v);
vis[v]=1;
sum[v]++;
if(sum[v]>n)
{
return 1;
}
}
}
}
}
return 0;
}
int main()
{
scanf("%d",&F);
while(F--)
{
int x,y,z;
k=1;
memset(e,0,sizeof(e));
memset(head,0,sizeof(head));
scanf("%d%d%d",&n,&m,&w);
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&x,&y,&z);
addedge(x,y,z);
addedge(y,x,z);
}
for(int i=1;i<=w;i++)
{
scanf("%d%d%d",&x,&y,&z);
addedge(x,y,-z);
}
if(spfa())
printf("YES\n");
else
printf("NO\n");
}
return 0;
}