P4951 [USACO01OPEN]Earthquake(二分&MST)

Posted Harris-H

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P4951 [USACO01OPEN]Earthquake(二分&MST)相关的知识,希望对你有一定的参考价值。

P4951 [USACO01OPEN]Earthquake(二分&MST)

01分数规划。

f − ∑ c o s t i ∑ t i ≥ a n s \\dfracf-\\sum cost_i\\sum t_i\\ge ans tifcostians

f − ( a n s × ∑ t i + ∑ c o s t i ) ≥ 0 f-(ans\\times \\sum t_i+\\sum cost_i)\\ge 0 f(ans×ti+costi)0

边权改为 − ( a n s × t i + c o s t i ) -(ans\\times t_i+cost_i) (ans×ti+costi)

二分答案 a n s ans ans

求最大生成树,如果大于等于0,说明答案可以更大。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull; 
const int N=505,M=1e4+5,inf=0x3f3f3f3f,mod=1e9+7;
const int hashmod[4] = 402653189,805306457,1610612741,998244353;
#define mst(a,b) memset(a,b,sizeof a)
#define db double
#define PII pair<int,int>
#define PLL pair<ll,ll>
#define x first
#define y second
#define pb emplace_back
#define SZ(a) (int)a.size()
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define per(i,a,b) for(int i=a;i>=b;--i)
#define ios ios::sync_with_stdio(false),cin.tie(nullptr) 
void Print(int *a,int n)
	for(int i=1;i<n;i++)
		printf("%d ",a[i]);
	printf("%d\\n",a[n]); 

template <typename T>		//x=max(x,y)  x=min(x,y)
void cmx(T &x,T y)
	if(x<y) x=y;

template <typename T>
void cmn(T &x,T y)
	if(x>y) x=y;

struct Kruskal
#define il inline	
	struct edge
		int u,v,t;
		db w;
		bool operator<(const edge &e)const
			return w>e.w;
		
	e[M],e1[M];
	int s[N];
	const db eps = 1e-6;
	il int find(int x)
		return s[x]==x?x:s[x]=find(s[x]);
	
	int n,m;
	db f;
	il void init()
		scanf("%d%d%lf",&n,&m,&f);
		rep(i,1,n) s[i] = i;
		rep(i,1,m)
			scanf("%d%d%lf%d",&e[i].u,&e[i].v,&e[i].w,&e[i].t);
		
	
	il void solve()
		double l = 0, r = f;
		while(r-l>eps)
			db mid = (l+r)/2;
			rep(i,1,m)  e1[i] = e[i] , e1[i].w = -e[i].w - e[i].t*mid;
			rep(i,1,n) s[i] = i;
			if(ck()) l = mid;
			else r = mid;
		
		printf("%.4f\\n",l);
	
	il bool ck()
		sort(e1+1,e1+m+1);
		int cnt = 0;
		db ans = 0;
		rep(i,1,m)
			int u = e1[i].u, v = e1[i].v;
			db  w = e1[i].w;
			u=find(u),v=find(v);
			if(u!=v)
				ans += w;
				s[u] = v;
				cnt++;
			
			if(cnt == n - 1) 
				break;
			
		
		return f+ans>=0;
	
T;
int main()
	T.init();
	T.solve();
	return 0;


以上是关于P4951 [USACO01OPEN]Earthquake(二分&MST)的主要内容,如果未能解决你的问题,请参考以下文章

P4377 [USACO18OPEN]Talent Show

[USACO 2001 OPEN] 地震

BZOJ 3127:[Usaco2013 Open]Yin and Yang(树点分治)

P1985 [USACO07OPEN]翻转棋 题解

luogu P1825 [USACO11OPEN]玉米田迷宫Corn Maze 题解

4579: [Usaco2016 Open]Closing the Farm