$$$
最短路径的演化题。
#include <stdio.h> #include <string.h> #include <queue> using namespace std; #define inf 0x3f3f3f3f struct Node { int v; int w; int next; }edge[2010]; int count[1010]; int dist[1010]; bool used[1010]; int head[1010]; int num,f; int n,m; void add_edge(int a,int b,int c,int d) { edge[num].v = b; edge[num].w = d - c; //权值存为该净赚的钱 edge[num].next = head[a]; head[a] = num++; } void init() { memset(used,false,sizeof(used)); memset(count,0,sizeof(count)); } int spfa() { init(); int i; queue<int>Q; for(i=1;i<=n;i++) { dist[i] = - inf; //初始为负无穷 } dist[1] = 0; used[1] = true; Q.push(1); while(!Q.empty()) { int u = Q.front(); Q.pop(); used[u] = false; count[u]++; if(count[u]>n) //该点进队次数大于n次,表示负圈存在 { return 1; } for(i=head[u];i!=-1;i=edge[i].next) { int v = edge[i].v; int w = edge[i].w; if(dist[v] < dist[u] + w) { dist[v] = dist[u] + w; if(used[v]==false) { used[v] = true; Q.push(v); } } } } return 0; } int main() { int T,t; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); int i,j; int a,b,c,d,e; num = 1;f = 0; memset(head,-1,sizeof(head)); for(i=1;i<=m;i++) { scanf("%d%d%d%d%d",&a,&b,&c,&d,&e); if(d+e>2*c) //这条道路来回都是能净赚钱 { f = 1; } add_edge(a+1,b+1,c,d); //个人爱好,从一号点开始存 add_edge(b+1,a+1,c,e); } if(f || spfa()) { printf("$$$\n"); } else { printf("%d\n",dist[n]); } } return 0; }