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 }

 

posted @ 2015-01-22 16:29  罗茜  阅读(236)  评论(0编辑  收藏  举报