首页 > 其他分享 >UVA11090 Going in Cycle!!题解

UVA11090 Going in Cycle!!题解

时间:2023-06-20 22:48:05浏览次数:47  
标签:rt ge int 题解 mid lt Going ans Cycle

题目大意

给定一个N个点M条边的带权有向图,求平均值最小的回路。

解法

看到这种题目,喜欢打暴力的我一下就想到:遍历整个图,找到每一个环,然后算出它们的平均值,最后比较出最小值。然而,呃...,会T飞...

既然我们不能暴力找最小值,那还有什么别的办法吗?

我们只需要输出一个最小值就行了,既然不能暴力遍历找环,那我们为何不能直接找答案呢?聪明的你一定想到了,找答案最一流(最高效)的,不就是二分答案吗?

确认了方向,接下来就是实现。

我们假设 \(ans\) 为我们找到的最小值,\(mid\) 为当前找到的值,\(m\) 为 \(mid\) 所在的环的边的条数,\(w_i\) 为 \(mid\) 所在的环的第 \(i\) 条边的边权。

首先:

\(mid = \frac{\sum\limits_{i = 1}^m{w_i}}{m}\)

\(\because mid \ge ans\)

\(\therefore \frac{\sum\limits_{i = 1}^m{w_i}}{m} \ge ans\)

通分一下:

\(\sum\limits_{i = 1}^m{w_i} \ge ans \cdot m\)

移项一下:

\(\sum\limits_{i = 1}^m{w_i} - ans \cdot m \ge 0\)

稍微变一下:

\(\sum\limits_{i = 1}^m{(w_i - ans)} \ge 0\)

这时,我们发现,环中的每一条边的边权减去 \(ans\) 后加起来的和是要大于0的。诶,等等,这不就是判负环吗?

也就是说,我们把每一条边的边权减去我们猜的答案 \(mid\),只要图中没有负环,就说明这个答案合法,可以猜小一点,反之则猜大。

于是乎,\(\text{check}\) 函数也就慢慢地浮现出来了:SPFA判负环

做到这里,我们就基本已经做完了这道题,接下来就可以看看我丑陋的代码了。

AC Code

#include<bits/stdc++.h>
using namespace std;
const int N = 55;
struct node
{
	int y;
	double w;
};
int T, t, n, m, cnt[N];
double dis[N];
bool vis[N];
vector<node> a[N];
void init()
{
	for(int i = 1; i <= n; i++)
		a[i].clear();
	return;
}
bool spfa(double s)
{
	memset(cnt, 0, sizeof(cnt));
	memset(vis, false, sizeof(vis));
	queue<int> q;
	for(int i = 1; i <= n; i++)//由于题目不保证图连通,所以是多起点SPFA
	{
		dis[i] = 0;
		q.push(i);
		vis[i] = true;
	}
	while(!q.empty())
	{
		int x = q.front();
		q.pop();
		vis[x] = false;
		int len = a[x].size();
		for(int i = 0; i < len; i++)
		{
			int y = a[x][i].y;
			double w = a[x][i].w - s;//注意这里边权要减去猜的答案
			if(dis[x] + w < dis[y])
			{
				dis[y] = dis[x] + w;
				cnt[y] = cnt[x] + 1;
				if(cnt[y] >= n)
					return true;
				if(vis[y])
					continue;
				q.push(y);
				vis[y] = true;
			}
		}
	}
	return false;
}
void slove()
{
	cin >> n >> m;
	init();
	double lt = 1e9, rt = -1e9;
	for(int i = 1; i <= m; i++)
	{
		int x, y;
		double w;
		cin >> x >> y >> w;
		a[x].push_back((node){y, w});
		lt = min(lt, w), rt = max(rt, w);//取左边界和右边界
	}
	lt--, rt++;
	double q = rt;//处理无解的情况准备的
	while(lt + 1e-6 < rt)//注意精度问题
	{
		double mid = (lt + rt) / 2;
		if(spfa(mid))
			rt = mid;
		else
			lt = mid;
	}
	if(q == rt)//判断是否无解
		printf("Case #%d: No cycle found.\n", ++t);//注意输出格式
	else
		printf("Case #%d: %.2f\n", ++t, rt);
	return;
}
int main()
{
	cin >> T;
	while(T--)
		slove();
	return 0;
}

完结撒花★,°:.☆( ̄▽ ̄)/:.°★★,°:.☆( ̄▽ ̄)/:.°★

标签:rt,ge,int,题解,mid,lt,Going,ans,Cycle
From: https://www.cnblogs.com/Sunseeker-Foam/p/UVA11090.html

相关文章

  • 题解 P4108【[HEOI2015]公约数数列】
    看到这种奇怪的操作,首先想到分块。以下记值域为\(w\),块长为\(B\)。前缀\(\gcd\)显然单调不增,而且后一个必须是前一个的因数,如果变化至少要减半。因此,我们知道,共有\(\mathcalO(\logw)\)个不同的前缀\(\gcd\)。我们可以接受对这些块暴力,只需要对前缀\(\gcd\)都相同的块......
  • uni-app微信小程序路由传参数据截断问题解决
    跳转页面:因为数据接受页面是富文本编辑器接收,所以先是将数据双引号处理了。数据太多太长,跳转页面只要用encodeURIComponent()函数将其数据处理后传过去constdetails=this.oneform.text.replace(/"/g,'\'')this.$tab.navigateTo(`/pages/common/editor/editor?details=${e......
  • 我是如何写题解的
    在算法竞赛中,写题解是我们不可或缺的一部分。它不仅能够帮助我们整理思路、总结经验,还可以与他人分享我们的解题思路和代码实现。然而,写一篇较完备的题解往往非常繁琐,需要手动复制粘贴题目链接、题号和AC代码,这不仅费时费力,还容易分散我们的注意力,因为我们写题解的核心内容是对题......
  • 【问题解决】 网关代理Nginx 301暴露自身端口号
    一般项目上常用Nginx做负载均衡和静态资源服务器,本案例中项目上使用Nginx作为静态资源服务器出现了很奇怪的现象,我们一起来看看。“诡异”的现象部署架构如下图,Nginx作为静态资源服务器监听8080端口,客户浏览器通过API网关的443端口(就是https)获取Nginx静态资源。现象是用户浏览......
  • react经典面试题解析--持续更新--day02
    二十一、高阶组件的使用场景1、数据获取:高阶组件可以在组件挂载时自动获取数据,并将数据通过props传递给被包装组件。2、权限控制:高阶组件可以检查用户是否有访问该组件的权限,从而决定是否渲染该组件。3、代码重用:高阶组件可以通过封装一些常见的逻辑,来提高代码的复用性。4、......
  • VONE客户端常见问题解决方案
    一、连接服务器失败打开vone客户端时,提示“连接服务器失败,请确认网络连接是否正常”,如下图:![image](https://img2023.cnblogs.com/blog/1224277/202306/1224277-20230620102849617-1673950342.png)![image](https://img2023.cnblogs.com/blog/1224277/202306/1224277-20230......
  • 题解 CF1840D【Wooden Toy Festival】
    不妨设\(a\)单调递增(无重复),显然如果\(n\le3\)答案就是\(0\)。显然答案\(k\)具有可二分性。也就是说,当\(k<k_0\)时一定不存在合法的\(x,y,z\),当\(k\gek_0\)时一定存在,\(k_0\)就是答案。因此二分答案,只需要验证答案\(k\)是否存在合法的\(x,y,z\)。为了覆盖到......
  • Codeforces Round 879 (Div. 2) 题解
    寄!大!了!Rating-=124.(恼)https://codeforces.com/contest/1834C.GamewithReversing发现\(\text{rev}(S)\toS\)和\(\text{rev}(T)\toT\)本质上是一样的。赛时就一个劲的对着\(S\)操作,,,。我们考虑单点修改在\(S\)上做,翻转操作在\(T\)上做。设\(\displaysty......
  • [ABC216G] 01Sequence 题解
    01Sequence题目大意构造一个满足\(m\)个形如\((l,r,x)\)的限制条件的\(01\)序列,其中\((l,r,x)\)表示区间\([l,r]\)的和不小于\(x\),你需要保证序列中\(1\)的个数最小。思路分析贪心的想,如果我们将限制按右端点排序,那么当遍历到一个区间,发现现有的和不满足限制条件......
  • 题解:【AT Educational DP Contest-O】 Matching
    题目链接来点位运算优化,目前也是拿下了洛谷最优解,比第二名快一倍:#include<bits/stdc++.h>#defineintlonglong#definebtp(x)__builtin_popcount(x)#definelowbit(x)((x)&(-x))usingnamespacestd;namespaceFastIO{template<typenameT=int>inlineTread()......