• 图论的常用算法


    在科研中,其实主要用的是最大流开源库,没有自己写过。

    为了在效率上优化,实际上maxflow/min-cut这个库写的还挺复杂,我曾看过一些,但只能做到在有代码的情况下弄懂。

    最小生成树——Prim

    int Prim(int** a, int n, int& maxRoad)
    {
        int mst=0;
        bool* visit=new bool[n];
        for(int i=0; i<n; ++i) visit[i]=false;
        int* curRow=new int[n];
        for(int i=0; i<n; ++i) curRow[i]=a[0][i];
        visit[0]=true;
    
        for(int i=1; i<n; i++)
        {
            int next=-1;
            int nextlen=0xfffff;
            for(int j=0; j<n; j++)
            {
                if(!visit[j] && curRow[j]<nextlen)
                {
                    next=j;
                    nextlen=curRow[j];
                }
            }
            if(next==-1) return -1;
            mst+=curRow[next];
            if(curRow[next]>maxRoad) maxRoad=curRow[next];
            visit[next]=true;
            for(int j=0; j<n; j++)
            {
                if(!visit[j] && a[next][j]<curRow[j]) curRow[j]=a[next][j];
            }
        }
        delete [] visit;
        delete [] curRow;
        return mst;
    }
    

    最短路径——Dijkstra

    int findMinNode(int** a, int s, int n, bool* visit)
    {
        int curmin=-1;
        int curlen=maxdist;
        for(int i=0; i<n; i++)
        {
            if(!visit[i] && a[s][i]<curlen)
            {
                curmin=i;
                curlen=a[s][i];
            }
        }
        return curmin;
    }
    
    void Dijkstra(int** a, int s, int n)
    {
        int* dist=new int[n];
        bool* visit=new bool[n];
        for(int i=0; i<n; i++)
        {
            if(i==s) dist[i]=0;
            else dist[i]=maxdist;
            visit[i]=false;
        }
        //visit[s]=true;
        for(int i=0; i<n; i++)
        {
            int curmin=findMinNode(a,s,n,visit);
            if(curmin==-1) return;
            visit[curmin]=true;
            for(int j=0; j<n; j++)
            {
                if(!visit[j] && dist[j]>dist[curmin]+a[curmin][j]) dist[j]=dist[curmin]+a[curmin][j];
            }
        }
    
        for(int i=0; i<n; i++)
        {
            if(i==0) cout << dist[i];
            else cout << " " << dist[i];
        }
        cout << endl;
    
        delete [] dist;
        delete [] visit;
        return;
    }
    

    最短路径——BellmanFord

    void BellmanFord(int** a, int s, int n)
    {
        int* dist=new int[n];
        for(int i=0; i<n; i++) dist[i]=maxdist;
        dist[s]=0;
    
        for(int i=1; i<=n-1; i++)
        {
            for(int j=0; j<n; j++)
            {
                for(int k=0; k<n; k++)
                {
                    if(dist[k]>dist[j]+a[j][k]) dist[k]=dist[j]+a[j][k];
                }
            }
        }
        for(int i=0; i<n; i++)
        {
            if(i==0) cout << dist[i];
            else cout << " " << dist[i];
        }
        cout << endl;
        delete [] dist;
        return;
    }
    

    最短路径——Floyd

    void Floyd(int** a, int s, int n)
    {
        int* ptr=new int[n*n];
        memset(ptr,maxdist,sizeof(int)*n*n);
        int** distmat=new int*[n];
        for(int i=0; i<n; i++)
        {
            distmat[i]=ptr+i*n;
        }
    
        for(int i=0; i<n; i++)
        {
            for(int j=0; j<n; j++)
            {
                distmat[i][j]=a[i][j];
            }
        }
    
        for(int i=0; i<n; i++)
        {
            for(int j=0; j<n; j++)
            {
                for(int k=0; k<n; k++)
                {
                    if(distmat[i][j]>distmat[i][k]+distmat[k][j]) distmat[i][j]=distmat[i][k]+distmat[k][j];
                }
            }
        }
        int* dist=distmat[s];
        for(int i=0; i<n; i++)
        {
            if(i==0) cout << dist[i];
            else cout << " " << dist[i];
        }
        cout << endl;
        delete [] distmat;
        delete [] ptr;
        return;
    }
    

    最大流——Dinic

    bool makeLevel(int** a, int s, int t, int* level, int n)
    {
        for(int i=0; i<n; i++) level[i]=-1;
        level[s]=0;
        queue<int> mq;
        mq.push(s);
        while(!mq.empty())
        {
            int len=mq.size();
            while(len--)
            {
                int curnode=mq.front();
                mq.pop();
                for(int i=0; i<n; i++)
                {
                    if(level[i]==-1 && a[curnode][i]>0)
                    {
                        level[i]=level[curnode]+1;
                        mq.push(i);
                    }
                }
            }
        }
        return level[t]!=-1;
    }
    
    int findFlow(int** a, int x, int t, int n, int* level, int flow)
    {
        if(x==t) return flow;
        int ret=0;
        for(int i=0; i<n; i++)
        {
            if(level[i]==level[x]+1 && a[x][i]>0 && (ret=findFlow(a,i,t,n,level,min(flow,a[x][i]))))
            {
                a[i][x]+=ret;
                a[x][i]-=ret;
                return ret;
            }
        }
        return 0;
    }
    
    void Dinic(int** a, int s, int t, int n)
    {
        int* level=new int[n];
        int flow=0;
        int maxflow=0xfffff;
        while(makeLevel(a,s,t,level,n))
        {
            flow+=findFlow(a,s,t,n,level,maxflow);
        }
        cout << flow << endl;
        delete [] level;
    }
    
  • 相关阅读:
    doker基础用法
    docker容器技术基础入门
    流模式
    装饰器模式
    适配器模式
    组合模式
    桥接模式
    观察者模式
    注册模式
    模板模式
  • 原文地址:https://www.cnblogs.com/moondark/p/3966926.html
Copyright © 2020-2023  润新知