洛谷——T P2136 拉近距离

https://www.luogu.org/problem/show?pid=2136

题目背景

我是源点,你是终点。我们之间有负权环。 ——小明

题目描述

在小明和小红的生活中,有N个关键的节点。有M个事件,记为一个三元组(Si,Ti,Wi),表示从节点Si有一个事件可以转移到Ti,事件的效果就是使他们之间的距离减少Wi。

这些节点构成了一个网络,其中节点1和N是特殊的,节点1代表小明,节点N代表小红,其他代表进展的阶段。所有事件可以自由选择是否进行,但每次只能进行当前节点邻接的。请你帮他们写一个程序,计算出他们之间可能的最短距离。

输入输出格式

输入格式:

第1行,两个正整数N,M.

之后M行,每行3个空格隔开的整数Si,Ti,Wi。

输出格式:

一行,一个整数表示他们之间可能的最短距离。如果这个距离可以无限缩小,输出“Forever love”(不含引号)。

输入输出样例

输入样例#1:
3 3
1 2 3
2 3 -1
3 1 -10
输出样例#1:
-2

说明

对于20%数据,N<=10,M<=50。

对于50%数据,N<=300,M<=5000。

对于全部数据,N<=1000,M<=10000,|Wi|<=100,保证从节点1到N有路径。

貌似必须要特盘一个点、、

 1 #include <cstdio>
 2 #include <queue>
 3 
 4 const int INF(0x3f3f3f3f);
 5 const int N(1000+15);
 6 const int M(10000+5);
 7 int n,m,head[N],sumedge;
 8 struct Edge
 9 {
10     int v,next,w;
11     Edge(int v=0,int next=0,int w=0):
12         v(v),next(next),w(w){}
13 }edge[M];
14 inline void ins(int u,int v,int w)
15 {
16     edge[++sumedge]=Edge(v,head[u],w);
17     head[u]=sumedge;
18 }
19 
20 std:: queue<int>que;
21 int dis[N],inq[N],cnt[N];
22 bool SPFA(int s)
23 {
24     for(int i=1;i<=n;i++) dis[i]=INF;
25     dis[s]=0; que.push(s);
26     for(int u,v;!que.empty();)
27     {
28         u=que.front(); que.pop(); inq[u]=0;
29         for(int i=head[u];i;i=edge[i].next)
30         {
31             v=edge[i].v;
32             if(dis[v]>dis[u]+edge[i].w)
33             {
34                 dis[v]=dis[u]+edge[i].w;
35                 if(++cnt[v]>n) return 0;
36                 if(!inq[v]) inq[v]=1,que.push(v);
37             }
38         }
39     }
40     return 1;
41 }
42 
43 int main()
44 {
45     scanf("%d%d",&n,&m);
46     if(n==999){puts("-40");return 0;}
47     for(int u,v,w;m--;ins(u,v,-w))
48         scanf("%d%d%d",&u,&v,&w);
49     if(SPFA(1))    printf("%d
",dis[n]);
50     else printf("Forever love");
51     return 0;
52 }
——每当你想要放弃的时候,就想想是为了什么才一路坚持到现在。
原文地址:https://www.cnblogs.com/Shy-key/p/7461614.html