仔细读了很长时间的题目,发现这是一道SPFA最长路+判正环的题目。
一旦题目出现正环 那么钱就是无限的了。直接输出-1
坐飞机我们可以认为连了一条负边权。
题目主要在于建模,实现并不算太难。
#include <cstdio> #include <algorithm> #include <cstring> #include <queue> using namespace std; struct node{ int u,v,w,next; node(){} node(int _u,int _v,int _w,int _next){ u = _u; v = _v; w = _w; next = _next; } }Edge[1005]; const int INF =0x3f3f3f3f; int n,m,Fly,Start,money,Max; int Count,head[1005],x,y,z; int dis[1005]; int toQue[1005]; bool inque[1005]; void AddEdge(int u,int v,int w){ Count++; Edge[Count]=node(u,v,w,head[u]); head[u]=Count; } bool spfa(){ dis[Start]=money; queue<int>Q; Q.push(Start); inque[Start]=true; while( !Q.empty() ){ int now = Q.front(); Q.pop(); inque[now]=false; toQue[now]++; if(toQue[now]>=n) return true; for(int i=head[now];i;i=Edge[i].next){ int w = Edge[i].w; int v = Edge[i].v; if(dis[now]+w>dis[v]){ dis[v] = dis[now]+w; if(!inque[v]){ Q.push(v); inque[v]=true; } } } } return false; } int main(){ memset(dis,-INF,sizeof(dis)); scanf("%d%d%d%d%d",&money,&m,&n,&Fly,&Start); for(int i=1;i<=m;i++){ scanf("%d%d",&x,&y); AddEdge(x,y,money); } for(int i=1;i<=Fly;i++){ scanf("%d%d%d",&x,&y,&z); AddEdge(x,y,money-z); } if( spfa() ){ printf("-1"); } else { for(int i=1;i<=n;i++) Max = max(Max,dis[i]); printf("%d\n",Max); } return 0; }