zoukankan      html  css  js  c++  java
  • NYOJ 973 天下第一 (最短路)

    题目链接

    描述

    AC_Grazy一直对江湖羡慕不已,向往着大碗吃肉大碗喝酒的豪情,但是“人在江湖漂,怎能

    不挨刀",”人在江湖身不由己",如果自己的武功太差,在江湖会死的很惨,但是AC_Grazy没有

    武功秘籍练不了绝世武功.有道是“山重水复疑无路,柳暗花明又一村”,在AC_Grazy家里面

    竟然藏着一本书,书名竟然叫做【超级外挂】,竟然能在各种武功之间进行转化,据说是他爷

    爷的爷爷的...爷爷传下来的...

    闲着无事便拿来看看,只看一眼便再也停不下了,只见上面写着“纵横武林打遍天下无敌手武功心法秘籍收录”.

    翻开第一篇一看竟然是【降龙十八掌】...

    心法只是一个修练武功的途径,重要的是真气的多少,于是他便想利用外挂让武功之间进行转

    化,来让真气无限增加,但是这个心法只能按照顺序转化,我们分别用 1号和2号来代替两种功法 当然转化会有一定的转化率f

    比如1 0.5 2 便是把 1的一半真气转化给2 ,为了简化问题,我们每次都从1号秘籍开始进行转化,如果其中一个秘籍转化断了,那么以后的功法就不能转换。

    • 输入
      输入:首先输入一个数 T(T<=20)表示T组数据然后输入两个数n(2<=n<=500)和
            m(1=<m<=2000)分别表示有n种秘籍,随后的m行分别输入
            秘籍u(n>=u>0) 转化率 f (0<f<=10)秘籍 v.(0<v<=n)
    
    • 输出
      输出:如果可以无限增加真气输出Yes否则输出No.
    • 样例输入
      2
      3 3
      1 2 2
      2 2 3
      3 2 1
      4 3
      1 2 2
      3 2 4
      4 2 3
    • 样例输出
      Yes
      No

    分析:

    所谓的能够无限增加真气,就是说路径中形成了环路,所以是否能够形成一个增加的环路成了这道题的一个判断标准。对于路径中的每一个点,都可能通过每一个到它的路径的权值来松弛,所以有多少条到它的路径就最多能够松弛几次,也就最多能够入队几次,如果入队的次数大于这个点的入度的话,也就意味着一定通过同一条路径松弛了最少两次,也就形成了所谓的环路。

    代码:

    #include<stdio.h>
    #include<iostream>
    #include<vector>
    #include<string.h>
    #include<queue>
    #define INF 0x3f3f3f3f
    using namespace std;
    vector<int> v[505];///一个动态的数组
    int bj[505];///标记那个点有没有访问过
    int du[505];///每一个城市的入度
    double dis[505];///距离
    int n,m;
    double Tu[505][505];///存储两点间的转化率
    void init()///初始化
    {
        memset(v,0,sizeof(v));
        memset(du,0,sizeof(du));
        for(int i=1; i<=n; i++)
            for(int j=1; j<=n; j++)
            {
                if(i==j)
                    Tu[i][j]=0;
                else
                    Tu[i][j]=-INF;
            }
    }
    
    bool spfa()
    {
        for(int i=1; i<=n; i++)
        {
            dis[i]=-INF;///因为这里要求的是最大值,所以初始化为最小值
            bj[i]=0;
        }
        dis[1]=1;///初始值
        int flag=1;
        bj[1]=1;///标记点访问过
        du[1]--;
        queue<int>q;
        q.push(1);
        while(!q.empty())
        {
            flag=q.front();
            q.pop();
            bj[flag]=0;///出队后要把标记释放掉,因为可能会多次用到这个点松弛
            for(int i=0; i<v[flag].size(); i++)
            {
                int t=v[flag][i];
                if(dis[t]<dis[flag]*Tu[flag][t])///当前的值比松弛后要小
                {
                    dis[t]=dis[flag]*Tu[flag][t];
                    if(bj[t]==0)
                    {
                        q.push(t);
                        bj[t]=1;
                        du[t]--;
                        if(du[t]<0)///形成环的标记
                            return true;
                    }
                }
            }
        }
        return false;
    }
    
    int main()
    {
        int T;
        scanf("%d",&T);
        int u,d;
        double f;
        while(T--)
        {
            scanf("%d%d",&n,&m);
            init();
            while(m--)
            {
                scanf("%d%lf%d",&u,&f,&d);
                v[u].push_back(d);
                du[d]++;
                Tu[u][d]=f;
            }
            if(spfa())
                printf("Yes
    ");
            else
                printf("No
    ");
        }
        return 0;
    }
  • 相关阅读:
    vi/vim键盘图
    PostgreSQL学习----命令或问题小结
    PostgreSQL学习----模式schema
    OSM
    Spring基础(9) : 自动扫描
    Spring基础(8) : properties配置文件
    Spring基础(8) : 延迟加载,Bean的作用域,Bean生命周期
    Spring基础(7) : Bean的名字
    Spring基础(6) : 普通Bean对象中保存ApplicationContext
    Spring基础(5): 构造函数注入无法处理循环依赖
  • 原文地址:https://www.cnblogs.com/cmmdc/p/6773998.html
Copyright © 2011-2022 走看看