P4926 [1007] 倍杀测量者

//https://www.luogu.com.cn/problem/P4926
#include <bits/stdc++.h>
using namespace std;
const int N=1e3+10,M=3*N;
int vow[N][4],score[N][2];
int head[N],Next[M],to[M],cnt;
double weight[M];
int update[N];
double dist[N];
int q[N];
bool enter[N];
int h,t;
int n,m1,m2;
void prepare(){
	h=t=0;
	cnt=1;
	memset(head,0,sizeof head);
	memset(dist,127,sizeof dist);
	memset(update,0,sizeof update);
	memset(enter,false,sizeof enter);
}
void addEdge(int u,int v,double w){
	Next[cnt]=head[u];
	to[cnt]=v;
	weight[cnt]=w;
	head[u]=cnt++;
}
bool spfa(int s){
	dist[s]=0;
	update[s]=1;
	q[t]=s;
	t=(t+1)%N;
	enter[s]=true;
	while(h!=t){
		int u=q[h];
		h=(h+1)%N;
		enter[u]=false;
		for(int ei=head[u];ei;ei=Next[ei]){
			int v=to[ei];
			double w=weight[ei];
			if(dist[v]>dist[u]+w){
				dist[v]=dist[u]+w;
				if(!enter[v]){
					if(++update[v]>n+1) return true;
					q[t]=v;
					t=(t+1)%N;
					enter[v]=true;
				}
			}
		}
	}
	return false;
}
bool check(double limit){
	prepare();
	for(int i=1;i<=n;i++) addEdge(0,i,0);
	for(int i=1;i<=m1;i++){
		if(vow[i][0]==1) addEdge(vow[i][1],vow[i][2],-log(-limit+vow[i][3]));
		else addEdge(vow[i][1],vow[i][2],log(limit+vow[i][3]));
	}
	for(int i=1;i<=m2;i++){
		addEdge(n+1,score[i][0],log(score[i][1]));
		addEdge(score[i][0],n+1,-log(score[i][1]));
	}
	return spfa(0);
}
double compute(){
	double l=0,r=1e10;
	while(r-l>=1e-6){
		double mid=(l+r)/2;
		if(check(mid)) l=mid;
		else r=mid;
	}
	return l;
}
int main(){
	scanf("%d%d%d",&n,&m1,&m2);
	for(int i=1;i<=m1;i++) scanf("%d%d%d%d",&vow[i][0],&vow[i][1],&vow[i][2],&vow[i][3]);
	for(int i=1;i<=m2;i++) scanf("%d%d",&score[i][0],&score[i][1]);
	double ans=compute();
	if(ans==0) puts("-1");
	else printf("%f\n",ans);
	return 0;
}
posted @ 2025-05-01 12:30  九三青梧  阅读(10)  评论(0)    收藏  举报