uva11090

本文介绍了一种使用二分法查找图中最小环平均权值的算法实现。通过枚举可能的最小平均权值,并利用DFS进行路径搜索,判断是否存在满足条件的环。适用于寻找加权图中最小子环的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目大意:

就最小的环的平均权值

思路:

二分法枚举最小平均权值,如果有满足的环就return true

这里用到了dfs找还,每次都减去平均权值,如果距离是>0的证明列举的平均权值是可以的

当然这用到的vis是为了让循环停止

代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<vector>
#include<cstring>
using namespace std;
const int maxn = 105;
const int INF = 0x3f3f3f3f;
int m, n;
struct node{
	int v;
	double	w;
};
double d[maxn];
int vis[maxn];
vector<node> g[maxn];
void init() {
	for(int i=1; i<=n; i++) g[i].clear();
	memset(vis, 0, sizeof(vis));
}
bool dfs(int x, double k) {
	vis[x] = 1;
	for(int i=0; i<g[x].size(); i++) {
		node& y = g[x][i];
		if(d[y.v] > d[x]+y.w-k) {
			d[y.v] = d[x]+y.w-k;
			if(vis[y.v]) return true;
			if(dfs(y.v, k)) return true;
		}
	}
	vis[x] = false;
	return false;
}
bool judge(double k) {
	memset(vis, 0, sizeof(vis));
	memset(d, 0, sizeof(d));
	
	for(int i=1; i<=n; i++) {
		if(dfs(i, k))  return true;
	}
	return false;
}
		
int main() {
	int kase;
	int num = 0;
	scanf("%d", &kase);
	int a, b;
	double c;
	while(kase--) {

		double sum = 0;
		double l, r;
		scanf("%d%d", &n, &m);
		init();
		for(int i=0; i<m; i++) {
			scanf("%d %d %lf", &a, &b, &c);
			g[a].push_back((node){b, c});
			sum += c;
		}
		l=0, r=sum+1;
		while(r-l>1e-6) {
			double mid = (r+l)/2.0;
			if(judge(mid)) r=mid;
			else l=mid;
		}
		        printf("Case #%d: ",++num);  
        if(!judge(r)) printf("No cycle found.\n");  
        else printf("%.2lf\n",l); 
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值