zoukankan      html  css  js  c++  java
  • poj 2240 Bellman-Flod 求环

    http://poj.org/problem?id=2240


    深刻体现了自己代码能力有问题外加改模板能力有问题。外加Debug有问题。以后做到:
    1、算法原理能够轻易弄出来。

    2、代码模板自己收集各种使用方法,以及已经的做过的改变的方法;

    3、没有完整清晰的思路不写程序;

    4、在Debug时没有基本绝对的把握,不点击“编译+执行”,不乱试

    回到这道题:
    我主要是想把Bellman-Ford的模板改为链式前向星的,然后就各种悲剧调试......

    学到三点:1、比例的初始化,求最大,源1.0,尚不可到达0, 

        2、Bellman-Ford求环,能够将原来的n-1次循环(就是最多经过n-1条边时最短路径),改为n次循环,当然也能够再把判负权的代码改了,相当于第n次。  这就是我以下贴的两个版本号的代码:
       3、链式前向星的Bellman-Ford模板例如以下

    两种版本号都是125ms AC--事实上一样

    n次循环:

    #include<cstdio>
    #include<cstring>
    #include <string>
    #include <map>
    #include <iostream>
    using namespace std;
    //#define INF 0x0f0f0f0f
    const double INF = 0;
    #define MAXN 1011
    #define Max(a,b) (a)>(b)?(a):(b)
    struct Node{
       int to;
       double w;
       int next;
    }edge[MAXN];
    int head[MAXN],s,n,m,path[MAXN];
    double dist[MAXN];//注意w以及该数组的类型
    using namespace std;
    void init()
    {
        memset(head,-1,sizeof(head));
        memset(path,-1,sizeof(path));
    
    }
    
    void addEdge(int u,int v,double w,int k)
    {
        edge[k].to=v;
        edge[k].w=w;
        edge[k].next=head[u];
        head[u]=k;/*起点为u的边为edge[k]*/
    }
    int Bellman_Ford(int v0)//v0--soure
    {
        for(int i=0;i<n;i++)dist[i]=0;//1.0;
        dist[v0]=1.0;
    
        for(int i=0;i<n;i++)
            for(int u=0;u<n;u++)
            {
                for(int j=head[u];j!=-1;j=edge[j].next)
                {
                    if(dist[u]*edge[j].w>dist[edge[j].to])
                    {
    
                            dist[edge[j].to]= dist[u]*edge[j].w;
                            path[edge[j].to]=u;
                    }
                }
    
            }
    
        if(dist[v0]>1.0)return 1;
        return 0;
    }
    
    int main()
    {
       // freopen("poj2240.txt","r",stdin);
        int icase=0,flag;
        double w;
        string u,v;
        string str;
        while(scanf("%d",&n) && n)
        {
            init();
            map<string, int>ss;
            for(int i=0;i<n;i++)
            {
                cin>>str;
                ss[str]=i;
            }
            scanf("%d",&m);
            for(int i=0;i<m;i++)
            {
                cin >> u >> w >> v;
                addEdge(ss[u],ss[v],w,i);
            }
    
            flag=1;
            for(int i=0;i<n;i++)
            {
    
                if(Bellman_Ford(i)){flag=0;printf("Case %d: Yes
    ",++icase);break;}
    
            }
            if(flag) printf("Case %d: No
    ",++icase);
        }
        return 0;
    }
    

    改负权代码  能够作为链式前向星的Bellman-Ford的模板:
    #include<cstdio>
    #include<cstring>
    #include <string>
    #include <map>
    #include <iostream>
    using namespace std;
    //#define INF 0x0f0f0f0f
    const double INF = 0;
    #define MAXN 1011
    #define Max(a,b) (a)>(b)?(a):(b)
    struct Node{
       int to;
       double w;
       int next;
    }edge[MAXN];
    int head[MAXN],s,n,m,path[MAXN];
    double dist[MAXN];//注意w以及该数组的类型
    using namespace std;
    void init()
    {
        memset(head,-1,sizeof(head));
        memset(path,-1,sizeof(path));
    
    }
    
    void addEdge(int u,int v,double w,int k)
    {
        edge[k].to=v;
        edge[k].w=w;
        edge[k].next=head[u];
        head[u]=k;/*起点为u的边为edge[k]*/
    }
    int Bellman_Ford(int v0)//v0--soure
    {
        for(int i=0;i<n;i++)dist[i]=0;//1.0;
        dist[v0]=1;
        int i,j,l,u,k;
    
        for(int i=1;i<n;i++)
            for(u=0;u<n;u++)
            {
                for(j=head[u];j!=-1;j=edge[j].next)
                {
                    if(dist[u]*edge[j].w>dist[edge[j].to])
                    {
                            dist[edge[j].to]= dist[u]*edge[j].w;
                            path[edge[j].to]=u;
                    }
                }
    
            }
    
        for(int j=0;j<n;j++)
        {
            for(k=head[j];k!=-1;k=edge[k].next)
            {
                if(edge[k].to == v0 && dist[j]*edge[k].w>1.0)//dist[edge[k].to])
                    return 1;
            }
        }
        return 0;
    }
    
    int main()
    {
        //freopen("poj2240.txt","r",stdin);
        int icase=0,flag;
        double w;
        string u,v;
        string str;
        while(scanf("%d",&n) && n)
        {
            init();
            map<string, int>ss;
            for(int i=0;i<n;i++)
            {
                cin>>str;
                ss[str]=i;
            }
            scanf("%d",&m);
            for(int i=0;i<m;i++)
            {
                cin >> u >> w >> v;
                addEdge(ss[u],ss[v],w,i);
            }
            flag=1;
            for(int i=0;i<n;i++)
            {
                if(Bellman_Ford(i)){flag=0;printf("Case %d: Yes
    ",++icase);break;}
    
            }
            if(flag) printf("Case %d: No
    ",++icase);
        }
        return 0;
    }
    


  • 相关阅读:
    Python 的 IDLE 编辑器
    Android中如何在Eclipse中关联源代码?(图文)
    HTMl5的存储方式sessionStorage和localStorage详解
    HTML的 <u> 标签
    CSS巧妙实现分隔线的几种方法
    关于ajax跨域请求(cross Domain)
    JQuery中$.ajax()方法参数都有哪些?
    最优雅,高效的javascript字符串拼接
    深入学习JavaScript: apply 方法 详解(转)——非常好
    jQuery.ajax() 函数详解
  • 原文地址:https://www.cnblogs.com/llguanli/p/8412927.html
Copyright © 2011-2022 走看看