• POJ1734无向图求最小环


    题目:http://poj.org/problem?id=1734

    方法有点像floyd。若与k直接相连的 i 和 j 在不经过k的情况下已经连通,则有环。

    注意区分直接连接和间接连接。

    * 路径记录很好,pre[i][j]表示 i 到 j 的路径上 j 的前一个点;用固定的 i 保证了不混乱。新加入k的时候注意维护。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    typedef long long ll;
    const ll N=105,INF=0x7fffffff;
    int n,m,pre[N][N],ans[N],cnt;
    ll f[N][N],mn=INF,b[N][N];
    int main()
    {
        int x,y;ll z;
        memset(f,1,sizeof f);
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d%lld",&x,&y,&z);
            if(b[x][y])
                f[x][y]=f[y][x]=b[x][y]=b[y][x]=min(f[x][y],z);
            else
            {
                f[x][y]=f[y][x]=z;
                b[x][y]=b[y][x]=z;
                pre[x][y]=x;pre[y][x]=y;
            }
        }
        for(int k=1;k<=n;k++)
            for(int i=1;i<=n;i++)
                for(int j=i+1;j<=n;j++)
                {
                    if(b[i][k]&&b[j][k]&&f[i][j]<INF)
                    {
                        ll tmp=f[i][j]+b[i][k]+b[j][k];//不是f[i][k] 
    //                    if(k==5&&i==2&&j==3)printf("tmp=%lld
    ",tmp);
                        if(tmp<mn)
                        {
    //                        printf("i=%d j=%d k=%d fij=%lld tmp=%lld
    ",i,j,k,f[i][j],tmp);
    //                        printf("ij=%lld ik=%lld jk=%lld
    ",f[i][j],f[i][k],f[j][k]);
                            mn=tmp;
                            cnt=0;
                            for(int u=j;u!=i;u=pre[i][u])ans[++cnt]=u;
                            ans[++cnt]=i;ans[++cnt]=k;
                        }
                    }
    //                if(f[i][k]>INF||f[k][j]>INF)continue;//
                    ll tmp=f[i][k]+f[k][j];
                    if(tmp<f[i][j])
                    {
                        f[i][j]=f[j][i]=tmp;
                        pre[i][j]=pre[k][j];
                        pre[j][i]=pre[k][i];
    //                    pre[i][j]=pre[j][i]=k;//错!不是直接相连! 
    //                    pre[i][k]=i;pre[j][k]=j;
    //                    pre[k][i]=k;pre[k][j]=k;//
                    }
                }
        if(cnt)for(int i=1;i<=cnt;i++)printf("%d ",ans[i]);
        else printf("No solution.");
        return 0;
    }
  • 相关阅读:
    linux系统调整磁盘分区
    Linux命令sort和uniq 的基本使用
    路由的执行优先级
    Linux命令xargs的使用
    wget命令的使用
    Linux环境下错误码及意义总结
    Linux下使用ip netns命令进行网口的隔离和配置ip地址
    MongoDB初始化创建管理员账户登录
    Python字符串的截取原理,下标的位置图示
    Python操作MongoDB查询时处理ObjectId
  • 原文地址:https://www.cnblogs.com/Narh/p/8783841.html
Copyright © 2020-2023  润新知