LightOj 1074 Extended Traffic (spfa+负权环)

题目链接:

  http://lightoj.com/volume_showproblem.php?problem=1074

题目大意:

  有一个大城市有n个十字交叉口,有m条路,城市十分拥挤,因此每一个路都有一个拥挤度,政府就出台了一个政策,对每一条路收取过路费,收取标准为(终点拥挤度 - 起点拥挤度 )3,,问每次询问m,输出1到m的最小花费,如果不能到达或者最小化费小于3的时候输出‘?’。

解题思路:

  用spfa。标记负环。

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <cstdlib>
  4 #include <queue>
  5 #include <vector>
  6 #include <iostream>
  7 #include <algorithm>
  8 using namespace std;
  9
 10 #define maxn 210
 11 #define INF 0x3f3f3f3f
 12
 13 struct Edge
 14 {
 15     int e, w;
 16     Edge(int e=0, int w=0):e(e),w(w){}
 17 };
 18
 19 vector<Edge>G[maxn];
 20 int dist[maxn], n;
 21 bool Cin[maxn];
 22 void init();
 23 int spfa ();
 24 void dfs (int u);
 25
 26 int main ()
 27 {
 28     int m, t, l=0, map[maxn];
 29     scanf ("%d", &t);
 30
 31     while (t --)
 32     {
 33         printf ("Case %d:\n", ++l);
 34         init ();
 35         scanf ("%d", &n);
 36
 37         for (int i=1; i<=n; i++)
 38             scanf ("%d", &map[i]);
 39
 40         scanf ("%d", &m);
 41         while (m --)
 42         {
 43             int a, b, num;
 44             scanf ("%d %d", &b, &a);
 45             num = (map[a] - map[b]) * (map[a] - map[b]) * (map[a] - map[b]);
 46             G[b].push_back (Edge(a, num));
 47         }
 48         spfa ();
 49         scanf ("%d", &m);
 50         while (m --)
 51         {
 52             int num;
 53             scanf ("%d", &num);
 54             if (Cin[num] || dist[num] < 3 || dist[num] == INF)
 55                 printf ("?\n");
 56             else
 57                 printf ("%d\n", dist[num]);
 58         }
 59     }
 60 }
 61 void init()
 62 {
 63     int i, j;
 64     memset (Cin, false, sizeof(Cin));
 65     for (i=0; i<maxn; i++)
 66     {
 67         G[i].clear();
 68         dist[i] = INF;
 69     }
 70 }
 71
 72 int spfa ()
 73 {
 74     queue<int>Q;
 75     bool vis[maxn];
 76     int cnt[maxn];
 77     memset (vis, false, sizeof(vis));
 78     memset (cnt, 0, sizeof(cnt));
 79     Q.push (1);
 80     cnt[1] = 1;
 81     dist[1] = 0;
 82
 83     while (!Q.empty())
 84     {
 85         int s = Q.front ();
 86         Q.pop ();
 87         vis[s] = false;
 88         int len = G[s].size();
 89
 90         for (int i=0; i<len; i++)
 91         {
 92             Edge x = G[s][i];
 93             if (Cin[x.e])
 94                 continue;
 95             if (dist[x.e] > dist[s] + x.w)
 96             {
 97                 dist[x.e] = dist[s] + x.w;
 98                 if (!vis[x.e])
 99                 {
100                     vis[x.e] = true;
101                     Q.push (x.e);
102                     cnt[x.e] ++;
103                     if (cnt[x.e] == n)//只要x.e在负环内,则在负环内的点可以到达的点,都没有最短路径
104                         dfs(x.e);
105                 }
106             }
107         }
108     }
109 }
110
111 void dfs (int u)
112 {
113     int len = G[u].size();
114     Cin[u] = true;
115     for (int i=0; i<len; i++)//u后面的点都没有最短回路,都应该标记
116
117     {
118         if (!Cin[G[u][i].e])
119             dfs (G[u][i].e);
120     }
121 }
时间: 2024-11-08 07:10:03

LightOj 1074 Extended Traffic (spfa+负权环)的相关文章

LightOJ 1074 Extended Traffic SPFA 消负环

分析:一看就是求最短路,然后用dij,果断错了一发,发现是3次方,有可能会出现负环 然后用spfa判负环,然后标记负环所有可达的点,被标记的点答案都是“?” #include<cstdio> #include<cstring> #include<queue> #include<cstdlib> #include<algorithm> #include<vector> #include<cmath> using namesp

SPFA(负环) LightOJ 1074 Extended Traffic

题目传送门 题意:收过路费.如果最后的收费小于3或不能达到,输出'?'.否则输出到n点最小的过路费 分析:关键权值可为负,如果碰到负环是,小于3的约束条件不够,那么在得知有负环时,把这个环的点都标记下,DFS实现. #include <cstdio> #include <cstring> #include <algorithm> #include <queue> using namespace std; const int N = 2e2 + 5; cons

(简单) LightOJ 1074 Extended Traffic,SPFA+负环。

Description Dhaka city is getting crowded and noisy day by day. Certain roads always remain blocked in congestion. In order to convince people avoid shortest routes, and hence the crowded roads, to reach destination, the city authority has made a new

LightOJ 1074 - Extended Traffic 【SPFA】

<题目链接> 题目大意:有n个城市,每一个城市有一个拥挤度Ai,从一个城市I到另一个城市J的时间为:(A(v)-A(u))^3.问从第一个城市到达第k个城市所花的时间,如果不能到达,或者时间小于3输出?否则输出所花的时间. 解题分析: 很明显,此题路段的权值可能为负,所以我们就不能用Dijkstra算法求最短路了.需要注意的是,当点存在负环的时候,就要将负环所能够到达的所有点全部标记,从起点到这些点的最短路是不存在的(因为假设如果存在最短路,那么只要途中在负环上多走几遍,那么重新算得的时间一定

LightOJ 1074 - Extended Traffic 【SPFA】(经典)

题目大意:有n个城市,每一个城市有一个拥挤度Ai,从一个城市I到另一个城市J的时间为:(A(v)-A(u))^3.问从第一个城市到达第k个城市所花的时间,如果不能到达,或者时间小于3输出?否则输出所花的时间. 解题分析: 很明显,此题路段的权值可能为负,所以我们就不能用Dijkstra算法求最短路了.需要注意的是,当点存在负环的时候,就要将负环所能够到达的所有点全部标记,从起点到这些点的最短路是不存在的(因为假设如果存在最短路,那么只要途中在负环上多走几遍,那么重新算得的时间一定会变少,所以不存

poj 3259 Wormholes 【最短路之负权环的判断】

Wormholes Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 54435   Accepted: 20273 Description While exploring his many farms, Farmer John has discovered a number of amazing wormholes. A wormhole is very peculiar because it is a one-way p

poj 3259 wormholes AC代码(负权环判断, Bellmanford)

#define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<string> #include<iomanip> #include<cstdlib> #include<cstdio> #include<vector> #include<algorithm> #include<cmath> #include<map> using namespa

Vijos1053 Easy sssp[spfa 负环]

描述 输入数据给出一个有N(2 <= N <= 1,000)个节点,M(M <= 100,000)条边的带权有向图. 要求你写一个程序, 判断这个有向图中是否存在负权回路. 如果从一个点沿着某条路径出发, 又回到了自己, 而且所经过的边上的权和小于0, 就说这条路是一个负权回路.如果存在负权回路, 只输出一行-1;如果不存在负权回路, 再求出一个点S(1 <= S <= N)到每个点的最短路的长度. 约定: S到S的距离为0, 如果S与这个点不连通, 则输出NoPath. 格

spfa判负权边

spfa判负环 如果一个点在spfa中被入队了大于n次 那么,我们就能肯定,有负环出现. 因为一个点入队时,他肯定被更新了一次. 所以........ 如果不存在负权环.这个点最多被更新节点数次 我们就可以利用这个性质判负环 亏我dijk写了一上午 题目 语文模板题 #include<cstdio> #include<iostream> #include<algorithm> #include<cstring> #include<queue> u