二分法

通往奥格瑞玛的道路(洛谷P1462)


题目大意

无向图中每走一条路会遭受攻击损失一定血量,当血量为负时则无法到达,每到一个城市都会收取一定费用包括起点和终点。现求在能到达终点的所有方案中找出城市缴费最多的一次中的最小值。

解题思路

二分法+dijkstra,二分城市缴纳费用查找节点。

未知的代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> PII;
const int N=1e4+5,inf=0x3f3f3f3f;
ll f[N];
ll n,m,b;
ll dist[N];
bool vis[N];
vector<PII>e[N];
void dijkstra(ll x){
	fill(dist+1,dist+n+1,inf);
	fill(vis+1,vis+n+1,false);
	priority_queue<PII,vector<PII>,greater<PII>>q;
	dist[1]=0;
	q.push({dist[1],1});
	while(!q.empty()){
		ll u=q.top().second;
		q.pop();
		if(vis[u])continue;
		vis[u]=true;
		for(auto&it:e[u]){
			ll v=it.first,w=it.second;
			if(f[v]>x)continue;
			if(!vis[v]&&dist[u]+w<dist[v]){
				dist[v]=dist[u]+w;
				q.push({dist[v],v});
			}
		}
	}
}
int main(){
	cin>>n>>m>>b;
	ll l=inf,r=0; 
	for(int i=1;i<=n;i++){
		cin>>f[i];
		r=max(r,f[i]);
	}
	l=max(f[1],f[n]);
	for(int i=1;i<=m;i++){
		ll u,v,w;
		cin>>u>>v>>w;
		e[u].push_back({v,w});
		e[v].push_back({u,w});
	}
	while(l<r){
		ll mid=(l+r)>>1;
	    dijkstra(mid);a
		if(dist[n]>b)l=mid+1;
		else r=mid;
	}
	dijkstra(l);
	if(dist[n]>b)cout<<"AFK"<<endl;
	else cout<<l<<endl;
	return 0;
}

进击的奶牛(洛谷 P1824)


题目大意

略,寻找一个最大最近距离。

解题思路

二分寻找目标距离。

未知的代码
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5;
int n,c,d[N];
int main(){
	cin>>n>>c;
	for(int i=1;i<=n;i++)cin>>d[i];
	sort(d+1,d+n+1);
	int l=d[1],r=d[n]-d[1];
	auto check=[](int x){
		int cnt=1,p=1;
		for(int i=2;i<=n;i++){
			if(d[i]-d[p]>=x){
				cnt++;
				p=i;
			}
		}
		return cnt>=c;	
	};
	int ans;
	while(l<r){
		int mid=(l+r)>>1;
		if(check(mid)){
			ans=mid;
			l=mid+1;
		}else r=mid;
	}
	cout<<ans<<endl;
	return 0;
}

Pie(poj 3122)


题目大意

分派,每个人分的派不能由不同派的小块组成,求每人最少能分多大体积。

解题思路

二分派的底面积,求最大体积。

未知的代码
#include<iostream>
#include<cmath>
#include<iomanip>
using namespace std;
#define PI acos(-1)
const int N=1e4+5;
const double eps=1e-8;
double a[N];
int t,n,f;
bool check(double x){
	int cnt=0;
	for(int i=1;i<=n;i++){
		cnt+=(int)(a[i]/x);
	}
	return cnt>=f;
}
int main(){
	cin>>t;
	while(t--){
		double sum=0;
		cin>>n>>f;
		f++;
		for(int i=1;i<=n;i++){
			cin>>a[i];
			a[i]*=a[i];
			sum+=a[i];
		}
		double l=0,r=sum/f,mid;
		while(r-l>eps){
			mid=(l+r)/2;
			if(check(mid))l=mid;
			else r=mid;
		}
		cout<<fixed<<setprecision(4)<<PI*l<<endl;
	}
	return 0;
}
posted @ 2024-02-17 18:03  Lost-in-love  阅读(46)  评论(0)    收藏  举报