• Luogu P4943 密室 题解


    闲扯

    这是紫题??

    做了昨天讲课听了一天的网络流,脑子都痛了,换点题做,结果随机调到这道题,发现貌似很好做的样子。。

    Solution

    首先我们分情况讨论一下。

    1. 罗恩去密室 (1) ,哈利去密室 (2)
    2. 罗恩去密室 (2) ,哈利去密室 (1)
    3. 罗恩吃瓜,哈利去两个密室。

    对于罗恩可以走的路,哈利一定是可以走的,所以哈利到两个密室的时间一定不小于罗恩。所以罗恩选择去他能去的密室中较近的一个,剩下一个由哈利去。

    为什么是对哒?

    考虑罗恩去较远的一个,那么哈利到较近的一个密室所用的时间是不大于罗恩所用时间的,所以答案为罗恩到较远密室所用的时间。

    考虑罗恩去较近的一个,那么哈利到较远的一个密室所用的时间是不大于罗恩所用时间的,所以答案不大于罗恩到较远密室所用的时间。

    综上,对于前两种情况,可以由以上策略解决。

    对于第 (3) 种情况,我们记录一下哈利到两间密室用时最短为多少,再找出两间密室间的最小距离,两者累加即为答案。

    最后输出再取一个最小值即可。

    (ps:) 对于前两种情况,答案应取用两人用时的最大值。

    Code

    #include<bits/stdc++.h>
    #define del(a,i) memset(a,i,sizeof(a))
    #define ll long long
    #define inl inline
    #define il inl void
    #define it inl int
    #define ill inl ll
    #define re register
    #define ri re int
    #define rl re ll
    #define mid ((l+r)>>1)
    #define lowbit(x) (x&(-x))
    #define INF 0x3f3f3f3f
    using namespace std;
    template<class T>il read(T &x){
    	int f=1;char k=getchar();x=0;
    	for(;k>'9'||k<'0';k=getchar()) if(k=='-') f=-1;
    	for(;k>='0'&&k<='9';k=getchar()) x=(x<<3)+(x<<1)+k-'0';
    	x*=f;
    }
    template<class T>il print(T x){
    	if(x/10) print(x/10);
    	putchar(x%10+'0');
    }
    ll mul(ll a,ll b,ll mod){long double c=1.;return (a*b-(ll)(c*a*b/mod)*mod)%mod;}
    it qpow(int x,int m,int mod){
    	int res=1,bas=x%mod;
    	while(m){
    		if(m&1) res=(res*bas)%mod;
    		bas=(bas*bas)%mod,m>>=1;
    	}
    	return res%mod;
    }
    const int MAXN = 5e4+5;
    int n,m,k,u,v,d,t1,t2,head[MAXN],num_edge,dis[MAXN],ans,now;
    struct Edge{
    	int next,to,dis;
    	Edge(){}
    	Edge(int next,int to,int dis):next(next),to(to),dis(dis){}
    }edge[MAXN<<2];
    il add_edge(int u,int v,int d){
    	edge[++num_edge]=Edge(head[u],v,d),head[u]=num_edge;
    	edge[++num_edge]=Edge(head[v],u,d),head[v]=num_edge;
    }
    bool tr[MAXN],onl[MAXN],fla;
    il dijkstra(int s,int type){
    	priority_queue<pair<int,int> > q;q.push(make_pair(0,s));
    	del(dis,0x3f),del(tr,0),dis[s]=0;
    	while(!q.empty()){
    		pair<int,int> tmp=q.top();q.pop();
    		ri pos=tmp.second;
    		if(tr[pos]) continue;
    		tr[pos]=1;
    		for(ri i=head[pos];i;i=edge[i].next){
    			if(type&&onl[edge[i].to]) continue;
    			if(dis[edge[i].to]>dis[pos]+edge[i].dis){
    				dis[edge[i].to]=dis[pos]+edge[i].dis;
    				if(!tr[edge[i].to]) q.push(make_pair(-dis[edge[i].to],edge[i].to));
    			}
    		}
    	}
    }
    int main()
    {
    //	freopen(".in","r",stdin);
    //	freopen(".out","w",stdout);
    	read(n),read(m),read(k);
    	for(ri i=1;i<=k;++i) read(u),onl[u]=1;
    	for(ri i=1;i<=m;++i) read(u),read(v),read(d),add_edge(u,v,d);
    	read(t1),read(t2);
    	dijkstra(1,1);
    	if(dis[t1]<dis[t2]) ans=dis[t1];
    	else ans=dis[t2],fla=1;
    	dijkstra(1,0),ans=max(ans,(fla?dis[t1]:dis[t2])),now=min(dis[t1],dis[t2]);
    	dijkstra(t1,0),now+=dis[t2];
    	printf("%d",ans<now?ans:now);
    	return 0;
    }
    

    总结

  • 相关阅读:
    Linux 下的类似Windows下Everything的搜索工具
    windows和linux环境下制作U盘启动盘
    程序调试手段之gdb, vxworks shell
    LeetCode 1021. Remove Outermost Parentheses (删除最外层的括号)
    LeetCode 1047. Remove All Adjacent Duplicates In String (删除字符串中的所有相邻重复项)
    LeetCode 844. Backspace String Compare (比较含退格的字符串)
    LeetCode 860. Lemonade Change (柠檬水找零)
    LeetCode 1221. Split a String in Balanced Strings (分割平衡字符串)
    LeetCode 1046. Last Stone Weight (最后一块石头的重量 )
    LeetCode 746. Min Cost Climbing Stairs (使用最小花费爬楼梯)
  • 原文地址:https://www.cnblogs.com/TheShadow/p/11386605.html
Copyright © 2020-2023  润新知