[洛谷P2136] 拉近距离 P1938

Description

小明在1号点 小红在n号点 他们之间的距离为。。。

给定n个点 m条边的有向图 每条边有起点s和终点t 以及从s转移到t距离会减少的w

输出他们之间可能的最短距离。如果这个距离可以无限缩小,输出“Forever love”(真是狗血的剧情)

Solution

因为又是无限  所以又要祭出我们的SPFA大法 (极不情愿)这里要2次SPFA 因为是单向嘛

关于环的问题这里不再多说了 P1938 可以去这里看看

 

Code

 

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <queue>
 4 #include <cstdlib>
 5 #include <cstring>
 6 using namespace std;
 7 int n, m, num;
 8 int head[10010], vis[1010], dis[1010], times[1010];
 9 struct emmm {
10     int next, to, dis;
11 }e[10010];
12 void add(int from, int to, int dis) {
13     e[++num].next = head[from];
14     e[num].to = to;
15     e[num].dis = dis;
16     head[from] = num;
17     return ;
18 }
19 void spfa(int s) {
20     memset(vis, 0, sizeof(vis));
21     memset(dis, 0x3f3f3f, sizeof(dis));
22     memset(times, 0, sizeof(times));
23     queue<int>q;
24     q.push(s);
25     vis[s] = 1;
26     dis[s] = 0;
27     times[s] = 1;
28     while (!q.empty()) {
29         int now = q.front();
30         q.pop();
31         vis[now] = 0;
32         for (int i = head[now];i; i = e[i].next) {
33             int v = e[i].to;
34             if (dis[v] > dis[now] + e[i].dis) {
35                 dis[v] = dis[now] + e[i].dis;
36                 if (!vis[v]) {
37                     q.push(v);
38                     vis[v] = 1;
39                     times[v]++;
40                     if (times[v] >= n)
41                         cout << "Forever love" << endl, exit(0);
42                 }
43             }
44         }
45     }
46     return;
47 }
48 int main() {
49     ios::sync_with_stdio(false);
50     cin >> n >> m;
51     for (int i = 1;i <= m; i++) {
52         int x, y, z;
53         cin >> x >> y >> z;
54         add(x, y, -z);
55     }
56     spfa(1);
57     int ans = dis[n];
58     spfa(n);
59     cout << min(ans, dis[1]) << endl;
60     return 0;
61 }
AC Code

 

猜你喜欢

转载自www.cnblogs.com/-sheldon/p/11371584.html