您的位置:首页 > 编程语言 > Go语言

UVa11090 Going in Cycle!!

2016-03-30 17:27 561 查看
UVa11090 Going in Cycle!!

链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=34650

【思路】

二分+SPFA。

二分平均值mid,如果有平均值小于mid的情况我们就缩小猜测值否则增大猜测值。如何判定?如果有平均值小于mid 则有:w1-mid+w2-mid+w3-mid+…<0 即将各条边权减mid后图中存在负圈,SPFA判负圈即可。

需要注意把int修改为double

【代码】

1 #include<cstdio>
2 #include<queue>
3 #include<cstring>
4 #include<algorithm>
5 using namespace std;
6
7 const int maxn = 100+10;
8 const double INF=1e10;
9 struct Edge{
10     int v,next;
11     double w;
12 }e[maxn*maxn];
13 int en,front[maxn];
14
15 int n,m;
16
17 inline void AddEdge(int u,int v,double w) {
18     en++; e[en].v=v; e[en].w=w; e[en].next=front[u]; front[u]=en;
19 }
20
21 bool SPFA_NC() {
22     int inq[maxn],cnt[maxn];
23     double d[maxn];
24     queue<int> q;
25     memset(cnt,0,sizeof(cnt));
26     memset(inq,0,sizeof(inq));
27     //添加一个超级源节点
28     for(int s=1;s<=n;s++)
29     {
30       d[s]=0; inq[s]=1; q.push(s);
31     }
32     while(!q.empty()) {
33         int u=q.front(); q.pop(); inq[u]=0;
34         for(int i=front[u];i>=0;i=e[i].next) {
35             int v=e[i].v; double w=e[i].w;
36             if(d[v]>d[u]+w) {
37                 d[v]=d[u]+w;
38                 if(!inq[v]) {
39                     inq[v]=1;
40                     q.push(v);
41                     if(++cnt[v]>n+1) return true;
42                 }
43             }
44         }
45     }
46     return false;
47 }
48
49 inline void init() {
50     en=0;
51     memset(front,-1,sizeof(front));
52 }
53
54 bool can(double x) {
55     for(int i=1;i<=en;i++) e[i].w-=x;
56     bool ans=SPFA_NC();
57     for(int i=1;i<=en;i++) e[i].w+=x;
58     return ans;
59 }
60
61 int main() {
62     int T;
63     scanf("%d",&T);
64     for(int kase=1;kase<=T;kase++) {
65         init();
66         scanf("%d%d",&n,&m);
67         double L=0,R=0;
68         int u,v; double w;
69         for(int i=0;i<m;i++) {
70             scanf("%d%d%lf",&u,&v,&w);
71             AddEdge(u,v,w);
72             if(w>R) R=w;
73         }
74         printf("Case #%d: ",kase);
75         if(!can(R+1)) printf("No cycle found.\n");
76         else
77         {
78            while(R-L>1e-3) {
79                 double M=L+(R-L)/2;
80                 if(can(M)) R=M;  //存在平均值小于mid的回路 则缩小猜测值
81                   else L=M;
82            }
83            printf("%.2lf\n",L);
84         }
85     }
86     return 0;
87 }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: