20140710 loop-I SPFA 二分答案

考试的时候写的dfs找环然后求平均值

当时感觉复杂度不是太高

结果Wa和T了一些后只有40分。。。

正解是二分答案再将所有边减去答案后用SPFA找有无负环即可

 1 #include <cstdio>
 2 #include <queue>
 3 #include <vector>
 4 using namespace std;
 5 #define N 660
 6 #define INF 0x3f3f3f+0.0
 7 
 8 struct edge {
 9     int u,v;
10 };
11 struct edge1 {
12     int u;
13     double len;
14 };
15 
16 int n,m;
17 int map[N][N];
18 vector <edge1> G[N];
19 bool vis[N];
20 double dis[N];
21 int outqueue[N];
22 edge e[1010];
23 
24 bool spfa(double k) {
25     for (int i=1;i<=n;i++) {
26         dis[i]=INF;
27         vis[i]=false;
28         outqueue[i]=0;
29     }
30     vis[1]=true;
31     dis[1]=0;
32     queue <int> q;
33     q.push(1);
34     while (!q.empty()) {
35         int v=q.front();
36         q.pop(); vis[v]=false;
37         outqueue[v]++;
38         if (outqueue[v]>n) return false;
39         for (int i=0;i<G[v].size();i++) {
40             edge1 e=G[v][i];
41             if (dis[v]+e.len-k<dis[e.u]) {
42                 dis[e.u]=dis[v]+e.len-k;
43                 if (!vis[e.u]) {
44                     vis[e.u]=true;
45                     q.push(e.u);
46                 }
47             }
48         }
49     }
50     return true;
51 }
52 
53 double min(double a,double b) {
54     return a<b?a:b;
55 }
56 
57 int main() {
58     scanf("%d%d",&n,&m);
59     for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) map[i][j]=INF;
60     for (int i=1;i<=m;i++) {
61         int u,v;
62         double cost;
63         scanf("%d%d%lf",&u,&v,&cost);
64         map[u][v]=min(map[u][v],cost);
65         e[i].u=u; e[i].v=v;
66     }
67     for (int i=1;i<=m;i++) {
68         edge1 e1;
69         e1.u=e[i].v; e1.len=map[e[i].u][e[i].v];
70         G[e[i].u].push_back(e1);
71     }
72     
73     double l=0.0,r=INF;
74     for (int k=0;k<100;k++) {
75         double mid=(l+r)/2;
76         if (spfa(mid)) l=mid;
77         else r=mid;
78     }
79     printf("%.2lf",l);
80 }
View Code
原文地址:https://www.cnblogs.com/fjmmm/p/3838238.html