zoukankan      html  css  js  c++  java
  • 套利

    套利

    题目传送门

    前言

    本题只有一个点,(DFS)应该会被(T)飞(我的(dfs)死得惨,但不排除能过)

    正解:最长路判环(推荐(SPFA)


    分析

    本题可以算是洛谷绿题中蛮简单的那种了(大概也就黄题?

    • 题目条件&我们的任务:
    1. 给出(N)个货币汇兑点

    2. 再给出(M)对汇率关系

    3. 要求判断从一个汇兑点开始兑换货币,当回到最初汇兑点时是否赚钱了(也可能回不到起点)

    结合生活实际很好理解,我们就直接来分析什么情况是(Yes),什么情况是(No)

    很显然,如果存在一个从起点开始的环第二次到达起点时钱变多了,就是(Yes)

    反之,上述两个条件任意一个不满足则是(No)

    • 为什么一定要用最长路?

    现实生活中,你肯定希望所有兑换结束后你手里的钱最多啊(不管是亏还是赚),而且有可能当前汇兑点对应多个其他汇兑点,所以采用最长路


    代码

    因为本来就简单,所以不多说了,直接上(Code)

    (PS:建议将(memset)清空换为(for)循环清空,这样可以快一点qwq)

    #include <bits/stdc++.h>
    using namespace std;
    bool flag;
    string s,ss;
    
    double c,dis[520010];
    int num[520010],vis[520010];
    int n,m,cnt,tot,now,head[520010];
    
    struct node {
    	int to,net;
    	double val;
    } e[520010];
    
    inline void add(int u,int v,double w) {
    	e[++tot].to=v;
    	e[tot].val=w;
    	e[tot].net=head[u];
    	head[u]=tot;
    }
    
    inline bool spfa(int ns) {
    	memset(vis,0,sizeof(vis));
    	memset(dis,0.0,sizeof(dis));
    	memset(num,0,sizeof(num));
    	dis[ns]=1.0;
    	queue<int> q;
    	q.push(ns);
    	vis[ns]=1;
    	num[ns]=1;
    	while(!q.empty()) {
    		int x=q.front();
    		q.pop();
    		vis[x]=0;
    		for(register int i=head[x];i;i=e[i].net) {
    			int v=e[i].to;
    			if(dis[v]<dis[x]*e[i].val) {
    				dis[v]=dis[x]*e[i].val;
    				if(num[v]==n) return true;
    				if(!vis[v]) {
    					vis[v]=1;
    					num[v]++;
    					q.push(v);
    				}
    			}
    		}
    	}
    	return false;
    }
    
    int main() {
    	while(scanf("%d",&n)) {
    		if(n==0) break;
    		now++;
    		cnt=0;
    		tot=0;
    		flag=false;
    		map<string,int> name;
    		memset(head,0,sizeof(head));
    		for(register int i=1;i<=n;i++) {
    			cin>>s;
    			name[s]=++cnt;
    		}
    		scanf("%d",&m);
    		for(register int i=1;i<=m;i++) {
    			cin>>s>>c>>ss;
    			add(name[s],name[ss],c);
    		}
    		printf("Case %d: ",now);
    		for(register int i=1;i<=cnt;i++) {
    			if(spfa(i)==true&&dis[i]>1.0) {
    				puts("Yes");
    				flag=true;
    				break;
    			}
    		}
    		if(flag==false) puts("No");
    	}
    	return 0;
    } 
    

  • 相关阅读:
    页面加载完成前的loading加载效果
    javascript数组常用的遍历方法
    JavaScript的值传递和引用传递
    操作iframe的一些方法
    函数依赖与数据库范式
    微信分享到朋友圈
    计算机原理基础-原反补
    async eachSeries如何按序列执行下去
    使用 VLOOKUP、INDEX 或 MATCH 查找值
    编码问题
  • 原文地址:https://www.cnblogs.com/Eleven-Qian-Shan/p/13269201.html
Copyright © 2011-2022 走看看