看透本质,是求最短路径的问题,向前的时间可以看做是负权重的边,然后向后的时间可以看做是正权重的边,最后能不能回到出发点,看的是有没有环路,一旦环路,就满足提前的要求,注意,无向边可以看做是两条有向边,图的存储可以采用结构体更为清楚,这道题用bellman还是略慢一些,明天要学一下spfa算法。
#include<iostream>
#include<queue>
#define Max 5610
#define verNum 1001
//#define Inifite 0xffffffff这里居然是-1。。。。
#define Inifite 100000000
using namespace std;
typedef struct Node
{
int from;
int to;
double dis;
}E;
int f,edgeNum;
int n,m,w;//n是点的个数,m是path的个数,w是wormhole的个数;
E edge[Max]; //存放的是边的信息
double dist[verNum];//存放的是最短路径的估计值,
int bellman()
{
int flag=0;
for(int i=0;i<n-1;i++)//记得这里是n-1次,也就是小于n-1;
{
flag=0;
for(int j=0;j<edgeNum;j++)
{
if(dist[edge[j].to]>dist[edge[j].from]+edge[j].dis)
{
dist[edge[j].to]=dist[edge[j].from]+edge[j].dis;
flag=1;
}
}
if(!flag)
break;
}
for(int p=0;p<edgeNum;p++)//这里是对边再进行一次松弛,不要弄错了
{
if(dist[edge[p].to]>dist[edge[p].from]+edge[p].dis)
return 1;
}
return 0;
}
int main()
{
cin >> f;
int from,to,flag=0;
double dis;
while(f--)
{
memset(dist,Inifite,sizeof(dist));
edgeNum=0;
flag=0;
cin >> n >> m >> w;
while(m--)
{
cin >> from >> to >> dis;
edge[edgeNum].from=from;
edge[edgeNum].to=to;
edge[edgeNum++].dis=dis;
edge[edgeNum].from=to;
edge[edgeNum].to=from;
edge[edgeNum++].dis=dis;
}
while(w--)
{
cin >> from >> to >> dis;
edge[edgeNum].from=from;
edge[edgeNum].to=to;
edge[edgeNum++].dis=-dis;
}
int is=bellman();
if(is)
cout << "YES" << endl;
else
cout <<"NO" << endl;
}
}