社区讨论

关于题目中的 0 点

P4926[1007] 倍杀测量者参与者 1已保存回复 0

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
0 条
当前快照
1 份
快照标识符
@lo13iqdo
此快照首次捕获于
2023/10/22 14:36
2 年前
此快照最后确认于
2023/11/02 14:06
2 年前
查看原帖
rt,不是很理解这里的 00 是一个虚点还是实点,我用的 00 和每个已经确定的点去连边来进行限制,然后用从 001n1\sim n 连一条权值为 00 的边来给初值,然后跑 SPFA 的时候最初 00 入队,但是这么写是错的;但如果我让 n+1n+11n1\sim n 连一条权值为 00 的边,n+1n+1 入队,同时还是用 00 来限制确定权值的点,这样跑的时候就是对的,为什么呢?/kel
不同的部分:
正确的:
CPP
for(re int i=0;i<=n;i++) cnt[i] = 0 , dis[i] = INF;
	dis[n+1] = 0 , vis[n+1] = 1 , q.push(n+1);

for(re int i=0;i<=n;i++) G[i].clear() , G[n+1].push_back({i,0});	
错误的:
CPP
	memset(cnt , 0 , sizeof cnt);
	for(re int i=1;i<=n;i++) dis[i] = INF;
	dis[0] = 0 , vis[0] = 1 , q.push(0);
	

	G[0].clear();
	for(re int i=1;i<=n;i++) G[i].clear() , G[0].push_back({i,0});
其余都是一样的,附上一个正确的完整代码:
CPP
#include<bits/stdc++.h>
//#define int long long
#define ll long long
#define next nxt
#define re register
#define il inline
const int N = 1e3 + 5;
const double INF = 0x7f7f7f7f;
const double eps = 1e-8;
using namespace std;
int max(int x,int y){return x > y ? x : y;}
int min(int x,int y){return x < y ? x : y;}

int n,m,t;
int cnt[N],opt[N],u[N],v[N];
double w[N],dis[N],val;
bitset <N> vis;
struct certain{
	int id;
	double val;
}a[N];
struct GENSHINIMPACT{
	int v;
	double w;
}; vector <GENSHINIMPACT> G[N];

il int read()
{
	int f=0,s=0;
	char ch=getchar();
	for(;!isdigit(ch);ch=getchar()) f |= (ch=='-');
	for(; isdigit(ch);ch=getchar()) s = (s<<1) + (s<<3) + (ch^48);
	return f ? -s : s;
}

il bool SPFA()
{
	queue <int> q;
	vis.reset();
	for(re int i=0;i<=n;i++) cnt[i] = 0 , dis[i] = INF;
	dis[n+1] = 0 , vis[n+1] = 1 , q.push(n+1);
	while(!q.empty())
	{
		int x = q.front(); q.pop();
		vis[x] = 0;
		for(re auto now : G[x])
		{
			int y = now.v; double w = now.w;
			if(dis[y] > dis[x] + w)
			{
				dis[y] = dis[x] + w;
				if(!vis[y])
				{
					cnt[y]++ , vis[y] = 1;
					if(cnt[y] >= n+1) return true;
					q.push(y);
				}
			}
		}
	}
	return false;
}

il bool check(double T)
{
	for(re int i=0;i<=n;i++) G[i].clear() , G[n+1].push_back({i,0});
	for(re int i=1;i<=m;i++)
	{
		if(opt[i] == 1)
		{
			if(w[i]-T < eps) continue;
			G[u[i]].push_back({v[i],-log(w[i]-T)});
		}
		if(opt[i] == 2) G[u[i]].push_back({v[i],log(w[i]+T)});
	}
	for(re int i=1;i<=t;i++)
	{
		G[0].push_back({a[i].id,log(a[i].val)});
		G[a[i].id].push_back({0,-log(a[i].val)});
	}
	return SPFA();
}

signed main()
{
	n = read() , m = read() , t = read();
	for(re int i=1;i<=m;i++) opt[i] = read() , u[i] = read() , v[i] = read() , scanf("%lf",&w[i]);
	for(re int i=1;i<=t;i++) a[i].id = read() , scanf("%lf",&a[i].val);
	double l = 0 , r = 1e9 , ans = 1e9+1;
	if(!check(0)) { cout << -1; return 0; }
	while(l+eps < r)
	{
		double mid = (l+r) / 2.0;
		if(check(mid)) ans = mid , l = mid;
		else r = mid;
	}
	printf("%.6lf",ans);
	return 0;
}

回复

0 条回复,欢迎继续交流。

正在加载回复...