zoukankan      html  css  js  c++  java
  • SPFA求负环

    ( O(n*m)spfa求负环时间复杂度较高\ 负环:图中存在一个环,环上个边的权值和为负数\ 01分数规划\ 求负环的方法,基于SPFA:\ (1)统计某个点入队的次数,如果某个点入队n次,则说明存在负环\ (2)统计当前每个点的最短路所含的边数,如果某点的最短路的边数>=n,则存在负环。\ 图中的负环不一定从1点点走到,它可以从任何一个位置开始走,走到负环。\ 处理方法:\ 1.一开始让所有n个点入队,即假设有一个虚拟源点,源点到n个点的距离为0;\ 2.为什么dis[N]不用初始化为0x3f3f3f3f,dis[N]可以任意初始化\ 因为,如果存在一个负环<==>某些点到虚拟源点的距离是(—无穷),\ 因为w[i]是有限值,spfa每在负环上转一圈,dis都会减一个有限值,\ 但是,dis[负环]上的点会变成负无穷,所以spfa一定会在某个点满足判断负环条件的时候退出\ 3.floyd和bellman-ford中0x3f3f3f3f/2的问题,如果1号点和其他点不连通,2->3,3会被2更新成0x3f3f3f3f-x eq0x3f3f3f3f 当所有点入队次数超过2n时,我们认为图中很大可能存在负环。(取巧做法) )

    1165. 单词环

    /*
    每个字符串当成一个点,1e5个点,每个字符串相同
    对于每个点,该点后可以连任何一个点,n-1
    边数为n^2级别
    将0~26^2每个十进制数看成一个点,每个字符串看成一条边
    从aa-zz编号从0~675,一共676个点
    1e5条边.
    */
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<queue>
    using namespace std;
    
    const int N=700,M=1e5+10;
    
    int h[N],e[M],ne[M],idx,w[M];
    int n,cnt[N];
    double dis[N];
    char str[M];
    bool st[N];
    void add(int a,int b,int c)
    {
        e[idx]=b,ne[idx]=h[a],w[idx]=c,h[a]=idx++;
    }
    // queue<int>que;
    int que[M*100],top;
    bool inline check(double mid)
    {
        memset(st,0,sizeof st);
        memset(cnt,0,sizeof cnt);
        //memset(que,0,sizeof que);重置top=0即可
        memset(dis,0,sizeof dis);
        top=0;
        for(int i=0;i<676;i++)
        {
            // que.push(i);
            que[++top]=i;
            st[i]=true;
        }
        int Count=0;
        while(top!=0)
        {
            // int t=que.front(),que.pop();
            int t=que[top--];
            st[t]=false;
    
            for(int i=h[t];~i;i=ne[i])
            {
                int j=e[i];
                if(dis[j]<dis[t]+w[i]-mid)
                {
                    dis[j]=dis[t]+w[i]-mid;
                    cnt[j]=cnt[t]+1;
                    if(++Count>=10000)return true;
                    if(cnt[j]>=N)
                        return true;
                    if(!st[j])
                    {
                        // que.push(j);
                        que[++top]=j;
                        st[j]=1;
                    }
                }
            }
        }
        return false;
    }
    
    int main()
    {
        while(scanf("%d",&n),n)
        {
            memset(h,-1,sizeof h);
            idx=0;
            for(int i=0;i<n;i++)
            {
                scanf("%s",str);
                int len=strlen(str);
                if(len>=2){
                    int left=(str[0]-'a')*26+str[1]-'a';
                    int right=(str[len-2]-'a')*26+str[len-1]-'a';
                    add(left,right,len);
                }
            }
            if(!check(0))//将M==0代入,没有正环
                cout<<"No solution"<<endl;
            else
            {
                double l=0,r=1000;
                while(r-l>1e-4)
                {
                    double mid=(l+r)/2;
                    if(check(mid))
                        l=mid;
                    else
                        r=mid;
                }
                // cout<<l<<endl;
                printf("%lf
    ",r);
            }
    
        }
        return 0;
    }
    坑点,memest()的时间复杂度是O(n)的,在多组测试数据中,使用for初始化比memset要快
    
  • 相关阅读:
    LeetCode 123. Best Time to Buy and Sell Stock III (stock problem)
    精帖转载(关于stock problem)
    LeetCode 122. Best Time to Buy and Sell Stock II (stock problem)
    LeetCode 121. Best Time to Buy and Sell Stock (stock problem)
    LeetCode 120. Triangle
    基于docker 搭建Elasticsearch5.6.4 分布式集群
    从零开始构建一个centos+jdk7+tomcat7的docker镜像文件
    Harbor实现容器镜像仓库的管理和运维
    docker中制作自己的JDK+tomcat镜像
    docker镜像制作---jdk7+tomcat7基础镜像
  • 原文地址:https://www.cnblogs.com/forward-985/p/14108577.html
Copyright © 2011-2022 走看看