• UVA 125 统计路径条数 FLOYD


    这道题目折腾了我一个下午,本来我的初步打算是用SPFA(),进行搜索,枚举出发点,看看能到达某个点多少次,就是出发点到该点的路径数,如果出现环,则置为-1,关键在于这个判环过程,如果简单只找到某个点是为环路上一点,即访问它的次数超过了所有点的点数目,这样就会出问题,因为它会影响其他点,下一步是否将它进入队列,如果进入,会造成无限循环,不进的话,根本得不出正确结果,后来我写了个judge函数,判断该点是否还能影响其他点,这样的话,因为要全图搜索,又TLE了。。。

    没办法,只好换了网站说的FLOYD;

    这是错误的代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    int u[1000],v[1000],w[1000],nt[1000],ft[50],vis[50],d[50],num[50];
    int n,e,maxn,sta[1000],test[1000];
    void addedge(int a,int b)
    {
        u[e]=a;
        v[e]=b;
        w[e]=0;
        nt[e]=ft[a];
        ft[a]=e++;
    }
    
    bool judge(int x)
    {
        int j,top=0;
        memset(vis,0,sizeof vis);
        //return dfs(x);
        test[top++]=x;
        vis[x]=1;
        while (top)
        {
            int nx=test[--top];
            if (num[nx]>=0) return 1;
            for (j=ft[nx];j>=0;j=nt[j])
            {
                int ns=v[j];
                if (!vis[ns])
                {
                    test[top++]=ns;
                    vis[ns]=1;
                }
            }
        }
        return 0;
    }
    void spfa(int root)
    {
        int i,j,top=0;
        memset(vis,0,sizeof vis);
        memset(num,0,sizeof num);
        sta[top++]=root;
        vis[root]=1;
        while (top)
        {
            int x=sta[--top];
            //cout<<x<<" pp "<<endl;
            vis[x]=0;
            for (i=ft[x];i>=0;i=nt[i])
            {
                int nx=v[i];
                //if (nx==x) continue;
                if (num[nx]>=0)
                  num[nx]++;
                if (num[nx]>maxn+1)
                {
                  num[nx]=-1;
                }
                //cout<<nx<<" nx num "<<num[nx]<<endl;
                //int temp;
                //cin>>temp;
                if (judge(nx))
                {
                    sta[top++]=nx;
                    vis[nx]=1;
                }
            }
        }
    }
    int main()
    {
        int cnt=0,i,j;
        while (scanf("%d",&n)!=EOF)
        {
            memset(ft,-1,sizeof ft);
            maxn=e=0;
            int a,b;
            for (i=1;i<=n;i++)
            {
                scanf("%d%d",&a,&b);
                addedge(a,b);
                maxn=maxn<a? a:maxn;
                maxn=maxn<b? b:maxn;
            }
            printf("matrix for city %d
    ",cnt++);
            for (i=0;i<=maxn;i++)
            {
                //cout<<i<<" pp "<<endl;
                spfa(i);
                for (j=0;j<=maxn;j++)
                {
                    printf("%d",num[j]);
                    if (j<maxn)
                        putchar(' ');
                }
                putchar('
    ');
            }
        }
        return 0;
    }

    这是AC的代码

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    int g[50][50];
    int d[50][50],num[50][50];
    int n,maxn;
    void init()
    {
        for (int i=0; i<50; i++)
        {
            for (int j=0; j<50; j++)
            {
                if (i==j) g[i][j]=0;
                else
                    g[i][j]=-1;
                d[i][j]=0;
            }
        }
    }
    int main()
    {
        int i,j,k,cnt=0;
        while (scanf("%d",&n)!=EOF)
        {
            init();
            int a,b;
            maxn=0;
            memset(num,0,sizeof num);
            for (i=1; i<=n; i++)
            {
                scanf("%d%d",&a,&b);
                g[a][b]=1;
                num[a][b]=1;
                maxn=maxn>a ? maxn:a;
                maxn=maxn>b ? maxn:b;
            }
            for (i=0; i<=maxn; i++)
            {
                for (j=0; j<=maxn; j++)
                {
                    for (k=0; k<=maxn; k++)
                    {
                        //if (j==k) continue;
                        if (num[j][i] && num[i][k])
                        num[j][k]+=num[j][i]*num[i][k];
                    }
                }
            }
            for (i=0;i<=maxn;i++)
            {
                if (num[i][i]>0)
                {
                    for (j=0;j<=maxn;j++)
                    {
                        for (k=0;k<=maxn;k++)
                        {
                            if (num[j][i] && num[i][k])
                                num[j][k]=-1;
                        }
                    }
                }
            }
            printf("matrix for city %d
    ",cnt++);
            for (i=0;i<=maxn;i++)
            {
                for (j=0;j<=maxn;j++)
                {
                    printf("%d",num[i][j]);
                    if (j<maxn) putchar(' ');
                }
                putchar('
    ');
            }
        }
        return 0;
    }

    FLOYD用这道题目原理很简单,就是因为它能算出所有点点的距离,因此用它来计算点点之间的路径数也是理所应当的可以。。关键在于成环的判断,一旦有某点num[k][k]>0,则该点必定在环内。。因此进行置-1操作。最后打印结果即可。

  • 相关阅读:
    当别人没说好,那么事就没达成协定
    设计模式(六):原型模式
    《一拳超人》观后感
    设计模式(五):中介者模式
    设计模式(四):单例模式与工厂模式
    设计模式(二):构造器模式与模块模式
    设计模式(一):概念小谈
    CSS代码记录
    java之如何实现调用启动一个可执行文件,exe
    file类之目录
  • 原文地址:https://www.cnblogs.com/kkrisen/p/3519586.html
Copyright © 2020-2023  润新知