http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2031

题目大意:

给定一个n个点m条边的加权有向图,求平均权值最小的回路。

思路:

用二分法求解。假设答案为mid,只需要判断是否存在平均值小于Mid的回路。怎么判断呢?假设一个包含k条边的回路,回路上各条边的权值为w1,w2……wk,那么平均值小于mid意味着 w1+w2+……wk< k* mid即:

(w1-mid)+(w2-mid)+……(wk-mid)<0

换句话说,只要把图中没一条边a,b的权值w(a,b)变为w(a,b)-mid,在判断图中有没有负权回路。

怎么判断负权回路呢?这就是SPFA的用法了,一个顶点入队列超过n次,就表示有回路。

记住这个不一定是联通的图。所以一开始要把所有的点加入队列。WA找了半天看了别人代码才发现。

---------------2014/01/26----------

想起可以增加一个点0,从该点到所有点的权值为0,那么可以保证改图连通,并且不会破坏负环~~~~~~

代码如下:

#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int MAXN=52;
const int INF=100000000;
struct edge
{
int to;
double val;
int next;
}e[MAXN*MAXN]; int head[MAXN],len,n,m;
void add(int from,int to,double val)
{
e[len].to=to;
e[len].val=val;
e[len].next=head[from];
head[from]=len++;
} bool spfa()
{
double dis[MAXN];
bool vis[MAXN]={0};
int cnt[MAXN]={0};
queue<int> q;
for(int i=1;i<=n;i++) //图可能是非联通的,所以一开始要把全部加入。WA在这里
dis[i]=INF; q.push(0);
vis[0]=cnt[0]=1;
dis[0]=0; while(!q.empty())
{
int cur=q.front();
q.pop();
vis[cur]=false;
for(int i=head[cur];i!=-1;i=e[i].next)
{
int id=e[i].to;
if(dis[cur] + e[i].val < dis[id])
{
dis[id]=dis[cur]+e[i].val;
if(!vis[id])
{
cnt[id]++;
vis[id]=true;
q.push(id);
if(cnt[cur] > n)
return true;
}
}
}
}
return false;
} void change(double x)
{
for(int k=1;k<=n;k++)
for(int i=head[k];i!=-1;i=e[i].next)
e[i].val+=x;
}
bool test(double x)
{
change(-x);
bool ok=spfa();
change(x);
return ok;
} int main()
{
int T;
scanf("%d",&T);
for(int ri=1;ri<=T;ri++)
{
len=0;
memset(head,-1,sizeof(head));
double L=INF,R=0;
scanf("%d%d",&n,&m);
for(int i=0;i<m;i++)
{
int from,to;
double val;
scanf("%d%d%lf",&from,&to,&val);
if(R< val)
R=val;
if(L > val)
L=val;
add(from,to,val);
}
for(int i=1;i<=n;i++)
add(0,i,0); printf("Case #%d: ",ri);
if(!test(R+1))
{
printf("No cycle found.\n");
continue;
} while(R-L > 1e-3) //浮点数判断大小要这样
{
double mid = L + (R-L)/2;
if(test(mid))
R = mid;
else
L = mid;
}
printf("%.2lf\n",R);
} return 0;
}

一开始全部加入队列版本

#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int MAXN=52;
const int INF=100000000;
struct edge
{
int to;
double val;
int next;
}e[MAXN*MAXN]; int head[MAXN],len,n,m;
void add(int from,int to,double val)
{
e[len].to=to;
e[len].val=val;
e[len].next=head[from];
head[from]=len++;
} bool spfa()
{
double dis[MAXN];
bool vis[MAXN];
int cnt[MAXN];
queue<int> q;
for(int i=1;i<=n;i++) //图可能是非联通的,所以一开始要把全部加入。WA在这里
{
dis[i]=INF;
vis[i]=true;
cnt[i]=1;
q.push(i);
} while(!q.empty())
{
int cur=q.front();
q.pop();
vis[cur]=false; for(int i=head[cur];i!=-1;i=e[i].next)
{
int id=e[i].to;
if(dis[cur] + e[i].val < dis[id])
{
dis[id]=dis[cur]+e[i].val;
if(!vis[id])
{
cnt[id]++;
vis[id]=true;
q.push(id);
if(cnt[cur] > n)
return true;
}
}
}
}
return false;
} void change(double x)
{
for(int k=1;k<=n;k++)
for(int i=head[k];i!=-1;i=e[i].next)
e[i].val+=x;
}
bool test(double x)
{
change(-x);
bool ok=spfa();
change(x);
return ok;
} int main()
{
int T;
scanf("%d",&T);
for(int ri=1;ri<=T;ri++)
{
len=0;
memset(head,-1,sizeof(head));
double L=INF,R=0;
scanf("%d%d",&n,&m);
for(int i=0;i<m;i++)
{
int from,to;
double val;
scanf("%d%d%lf",&from,&to,&val);
if(R< val)
R=val;
if(L > val)
L=val;
add(from,to,val);
}
printf("Case #%d: ",ri);
if(!test(R+1))
{
printf("No cycle found.\n");
continue;
} while(R-L > 1e-3) //浮点数判断大小要这样
{
double mid = L + (R-L)/2;
if(test(mid))
R = mid;
else
L = mid;
}
printf("%.2lf\n",R);
} return 0;
}

UVA 11090 - Going in Cycle!! SPFA的更多相关文章

  1. UVA 11090 Going in Cycle!! SPFA判断负环+二分

    原题链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem ...

  2. UVA - 11090 - Going in Cycle!!(二分+差分约束系统)

    Problem  UVA - 11090 - Going in Cycle!! Time Limit: 3000 mSec Problem Description You are given a we ...

  3. UVA 11090 - Going in Cycle!!(Bellman-Ford)

    UVA 11090 - Going in Cycle!! option=com_onlinejudge&Itemid=8&page=show_problem&category= ...

  4. UVA 11090 Going in Cycle!! 环平均权值(bellman-ford,spfa,二分)

    题意: 给定一个n个点m条边的带权有向图,求平均权值最小的回路的平均权值? 思路: 首先,图中得有环的存在才有解,其次再解决这个最小平均权值为多少.一般这种就是二分猜平均权值了,因为环在哪也难以找出来 ...

  5. UVA 11090 : Going in Cycle!! 【spfa】

    题目链接 题意及题解参见lrj训练指南 #include<bits/stdc++.h> using namespace std; const double INF=1e18; ; ; in ...

  6. UVa 11090 Going in Cycle!!【Bellman_Ford】

    题意:给出n个点m条边的加权有向图,求平均值最小的回路 自己想的是用DFS找环(真是too young),在比较找到各个环的平均权值,可是代码实现不了,觉得又不太对 后来看书= =好巧妙的办法, 使用 ...

  7. UVA 11090 Going in Cycle!!(二分答案+判负环)

    在加权有向图中求平均权值最小的回路. 一上手没有思路,看到“回路”,第一想法就是找连通分量,可又是加权图,没什么好思路,那就转换题意:由求回路权值->判负环,求最小值->常用二分答案. 二 ...

  8. UVA 11090 Going in Cycle!!

    要求给定的图的中平均权值最小的环,注意处理自环的情况就能过了. 按照w1+w2+w3+….wn < n*ave的不等式,也就是(w1-ave) + (w2-ave) +…..(wn-ave) & ...

  9. UVa 11090 Going in Cycle!! (Bellman_Ford)

    题意:给定一个加权有向图,求平均权值最小的回路. 析:先十分答案,假设答案是 ans,那么有这么一个回路,w1+w2+w3+...+wk < k*ans,这样就是答案太大,然后移项可得,(w1- ...

随机推荐

  1. C语言-常量指针与指针常量

    最近倪健问我一个问题,他说:什么是常指针?什么是指向常变量的指针?请举例说明 我查阅资料后这么回答他了, 指针常量(常指针):int * const p : 指针是一个常量,也就是说它始终指向那个地址 ...

  2. wget 指令学习之递归抓取文档技巧

    在线上阅读文档的时候,有没有想将它抓取到本地,以备没有网的时候阅读只需? 先上指令: $ wget --user-agent="Mozilla/5.0 (X11; Linux x86_64) ...

  3. ZOJ 3524 Crazy Shopping

    Crazy Shopping Time Limit: 3000ms Memory Limit: 65536KB This problem will be judged on ZJU. Original ...

  4. 下载编译 Android wear 源代码,尝试制作可穿戴设备功能

    体验 Android Wear 缘由: Android wear 代码公布已经非常久了.一直没有尝试,这里是个编译的过程和步骤,假设要尝试.本文假定读者已经有下载编译 Android  的经验,假设没 ...

  5. POJ--2516--Minimum Cost【最小费用最大流】

    链接:http://poj.org/problem?id=2516 题意:有k种货物,n个客户对每种货物有一定需求量,有m个仓库.每一个仓库里有一定数量的k种货物.然后k个n*m的矩阵,告诉从各个仓库 ...

  6. Oracle APEX 4.2公布RESTful Webservice

    Purpose This tutorial covers creating a RESTful Web Service and accessing the Web Service through an ...

  7. APACHE2.4 指定目录中的字符编码

    APACHE2.4 指定目录中的字符编码 xampp 的 apache2.4 默认字符编码是西文,中文字符显示乱码,在 httpd.conf 没有 AddDefaultCharset utf-8 这样 ...

  8. php资源类型变量

    php资源类型变量 一.总结 1. php资源类型变量:用来打开文件.数据库连接.图形画布区域等的一种特殊变量,比如FILE *fp;  二.PHP: Resource 资源类型 Resource 资 ...

  9. js---BOM 的理解方法

    windows 方法 window.close(); //关闭窗口   window.alert("message"); //弹出一个具有OK按钮的系统消息框,显示指定的文本   ...

  10. javafx spring

    javafx spring http://files.cnblogs.com/files/rojas/airhacks_control.zip