• 浙大集训day3:A


    浙大集训day3:A

    目前情况非常危险:

    B和M都是玩家,另一个人是冒名顶替者。

    冒名顶替者一旦和两个人的位置重合,就可以杀死其中一个人。

    给出两个人的起点,冒名顶替者的起点,它们要去共同的终点。

    默认冒名顶替者的速度是\(1\)

    询问两个人的最小速度,使得可以安全的抵达终点,不被冒名顶替者拦截。

    做法:

    先处理出两个起点到所有点的dij。

    然后需要找到一条路径,我抵达每个点都比另一个人要快,这条路径的贡献就是这些点的最大速度,这些最大速度取最小

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1e5+100;
    const int inf=1e9;
    typedef long long ll;
    vector<pair<int,int> > g[maxn];
    int d[maxn][3];
    unsigned long long c[maxn][3];
    int vis[maxn];
    int C,I,D,n,m;
    struct qnode {
    	int v,w;
    	qnode (int vv,int ww) {
    		v=vv;
    		w=ww;
    	}
    	bool operator < (const qnode &r) const {
    		return w>r.w;
    	}
    };
    double ans=1e9;//有一条路径,我抵达每个点都比另一个人要快,这条路径的贡献就是这些点的最大速度,这些最大速度取最小
    //计算起点到每个点要多少速度才能抵达 
    vector<pair<int,int> > tp[maxn];//后继网络 
    void dij (int s,int f) {
    	for (int i=1;i<=n;i++) {
    		vis[i]=0;
    		d[i][f]=inf;
    		c[i][f]=0;
    	}
    	priority_queue<qnode> q;
    	d[s][f]=0;
    	c[s][f]=1;
    	q.push(qnode(s,d[s][f]));
    	while (q.size()) {
    		qnode tt=q.top();
    		q.pop();
    		int u=tt.v;
    		if (vis[u]) continue;
    		vis[u]=1;
    		for (pair<int,int> it:g[u]) {
    			int v=it.first;
    			int w=it.second;
    			if (vis[v]) continue;
    			if (d[u][f]+w<d[v][f]) {
    				d[v][f]=d[u][f]+w;
    				c[v][f]=c[u][f];
    				q.push(qnode(v,d[v][f]));
    			}
    			else if (d[u][f]+w==d[v][f]) {
    				c[v][f]+=c[u][f];
    			}
    		}
    	}
    }
    int b[maxn],dd[maxn],in[maxn];
    double pp[maxn],pd[maxn];
    struct qqnode {
    	int v;
    	double w;
    	qqnode (int vv,double ww) {
    		v=vv;
    		w=ww;
    	}
    	bool operator < (const qqnode &r) const {
    		return w>r.w;
    	}
    };
    void dij1 (int s) {
    	priority_queue<qqnode> q;
    	for (int i=1;i<=n;i++) {
    		vis[i]=0;
    		pd[i]=inf;
    	}
    	q.push(qqnode(s,pp[s]));
    	pd[s]=pp[s];
    	while (q.size()) {
    		qqnode tt=q.top();
    		q.pop();
    		int u=tt.v;
    		double w=tt.w;
    		if (vis[u]) continue;
    		vis[u]=1;
    		for (pair<int,int> it:g[u]) {
    			int v=it.first;
    			if (max(pd[u],pp[v])<pd[v]) {
    				pd[v]=max(pd[u],pp[v]);
    				q.push(qqnode(v,pd[v]));
    			}
    		}
    	}
    }
    int main () {
    	scanf("%d%d",&n,&m);
    	while (m--) {
    		int u,v,w;
    		scanf("%d%d%d",&u,&v,&w);
    		g[u].push_back(make_pair(v,w));
    		g[v].push_back(make_pair(u,w));
    	}
    	scanf("%d%d%d",&C,&I,&D);
    	dij(C,0);
    	dij(D,1);
    	dij(I,2);
    	if (d[D][0]==inf) return printf("-1\n"),0;
    	if (d[D][2]==inf) return printf("0.000000\n"),0;
    	if (d[D][2]==0) return printf("-1\n"),0;
    	for (int i=1;i<=n;i++) {
    		if (d[i][2]==0) pp[i]=inf;
    		else pp[i]=1.0*d[i][0]/d[i][2];//计算最快到这个点的速度 
    	}
    	dij1(C);
    	if (pd[D]==inf) return printf("-1\n"),0; 
    	printf("%.6f\n",pd[D]);
    }
    
    
  • 相关阅读:
    2017.10.04
    2017.10.03
    Luogu P3110 [USACO14DEC]驮运Piggy Back
    Luogu P2176 [USACO14FEB]路障Roadblock
    Luogu P3797 妖梦斩木棒
    数列分块入门1-9 By hzwer
    CodeForces 【20C】Dijkstra?
    Luogu P2835 刻录光盘
    Luogu P1692 部落卫队
    Luogu P2847 [USACO20DEC]Moocast(gold)奶牛广播-金
  • 原文地址:https://www.cnblogs.com/zhanglichen/p/15548906.html
Copyright © 2020-2023  润新知