zoukankan      html  css  js  c++  java
  • 图论模板集合

    二分图模板

    匈牙利算法 时间复杂度O(n^3)

    int n1,n2,k;
    
    //n1,n2为二分图的顶点集,其中x∈n1,y∈n2
    int map[N][N],vis[N],link[N];
    //link记录n2中的点y在n1中所匹配的x点的编号
    int find(int x)
    {
        int i;
        for(i=1;i<=n2;i++)
        {
            if(map[x][i]&&!vis[i])//x->i有边,且节点i未被搜索
            {
                vis[i]=1;//标记节点已被搜索
                //如果i不属于前一个匹配M或被i匹配到的节点可以寻找到增广路
                if(link[i]==0||find(link[i]))
                {
                    link[i]=x;//更新
                    return 1;//匹配成功
                }
            }        
        }
        return 0;
    }

    Hopcroft-Karp算法 时间复杂度O(n^0.5*e)

    讲解参照

    
    
    vector<int>ed[N];
    int xlink[N],ylink[N];/*xlink[i]表示左集合顶点所匹配的右集合顶点序号,ylink[i]表示右集合i顶点匹配到的左集合顶点序号。*/ 
    bool vis[N]; //寻找增广路的标记数组
    int dx[N],dy[N];/*dx[i]表示左集合i顶点的距离编号,dy[i]表示右集合i顶点的距离编号*/  
    int dis,n;
    void init()
    {
        memset(xlink,-1,sizeof(xlink));
        memset(ylink,-1,sizeof(ylink));
    }
    int bfs()
    {
        memset(dx,-1,sizeof(dx));
        memset(dy,-1,sizeof(dy));
        int i;
        queue<int>q;
        dis = INF;
        for(i = 1 ; i <= n;i++)
        if(xlink[i]==-1)
        {
            q.push(i);
            dx[i] = 0;
        }
        while(!q.empty())
        {
            int u = q.front(); q.pop();
            if(dx[u]>dis) break;
            for(i = 0 ;i < ed[u].size() ; i++)
            {
                int v = ed[u][i];
                if(dy[v]==-1)
                {
                    dy[v] = dx[u]+1;
                    if(ylink[v]==-1) dis = dy[v];
                    else
                    {
                        dx[ylink[v]] = dy[v]+1;
                        q.push(ylink[v]);
                    }
                }
            }
        }
        return dis!=INF;
    }
    int find(int u)
    {
        int i;
        for(i = 0;i < ed[u].size() ; i++)
        {
            int v = ed[u][i];
    
            if(vis[v]||dy[v]!=dx[u]+1) continue;
            vis[v] = 1;
            if(ylink[v] != -1&&dy[v]==dis) continue;
            if(ylink[v]==-1||find(ylink[v])) {
                ylink[v] = u;
                xlink[u] = v;
                return 1;
            }
        }
        return 0;
    }
    int hk()
    {
        int ans = 0,i;
        while(bfs())
        {
    
            memset(vis,0,sizeof(vis));
            for(i = 1 ; i <= n ;i++)
            {
                if(xlink[i]==-1)
                ans+=find(i);
            }
        }
        return ans;
    }

     最大流模板 

    Edmonds-Karp算法 时间复杂度O(n*e^2)

    int path[N],flow[N],gh[N][N],st,en;
    int bfs()
    {
        int i;
        memset(path,-1,sizeof(path));
        for(i = 1 ; i <= en ; i++)
        flow[i] = INF;
        queue<int>q;
        q.push(1);
        while(!q.empty())
        {
            int tk = q.front();
            q.pop();
            if(tk==en)
            break;
            for(i = 1 ; i <= en ; i++)
            {
                if(path[i]==-1&&gh[tk][i])
                {
                    path[i] = tk;
                    flow[i] = min(flow[tk],gh[tk][i]);
                    q.push(i);
                }
            }
        }
        if(path[en]==-1)
        return -1;
        return flow[en];
    }
    int km()
    {
        int now,pre,sum=0,k;
        while((k=bfs())!=-1)
        {
            sum+=k;
            now = en;
            while(now!=st)
            {
                pre = path[now];
                gh[pre][now]-=k;
                gh[now][pre]+=k;
                now = pre;
            }
        }
        return sum;
    }

     dinic算法 O(n*n*m)

    效率相对于上面快了很多

    #define INF 0x3f3f3f
    const int N = 415;
    #define M 160015
    struct node
    {
        int u,v,next;
        int w;
    } edge[M<<1];
    int head[N],t,vis[N],pp[N],dis[N];
    int o[N];
    int st,en;
    int x[N][N],f[N];
    void init()
    {
        t=0;
        memset(head,-1,sizeof(head));
    }
    void add(int u,int v,int w)
    {
        edge[t].u = u;
        edge[t].v = v;
        edge[t].w = w;
        edge[t].next = head[u];
        head[u] = t++;
        edge[t].u = v;
        edge[t].v = u;
        edge[t].w = 0;
        edge[t].next = head[v];
        head[v] = t++;
    }
    int bfs()
    {
        int i,u;
        int w;
        memset(dis,-1,sizeof(dis));
        queue<int>q;
        q.push(st);
        dis[st] = 0;
        while(!q.empty())
        {
            u = q.front();
            q.pop();
            for(i = head[u] ; i != -1 ; i = edge[i].next)
            {
                int v = edge[i].v;
                w = edge[i].w;
                if(dis[v]<0&&w>0)
                {
                    dis[v] = dis[u]+1;
                    q.push(v);
                }
            }
        }
        if(dis[en]>0) return 1;
        return 0;
    }
    int dfs(int u,int te)
    {
        int i;
        int s;
        if(u==en) return te;
        for(i = head[u] ; i != -1 ; i = edge[i].next)
        {
            int v = edge[i].v;
            int w = edge[i].w;
            if(w>0&&dis[v]==dis[u]+1&&(s=dfs(v,min(te,w))))
            {
                edge[i].w-=s;
                edge[i^1].w+=s;
                return s;
            }
        }
        dis[u] = -1;
        return 0;
    }
    int dinic()
    {
        int flow = 0;
        int res;
        while(bfs())
        {
            while(res = dfs(st,INF))
            flow+=res;
        }
        return flow;
    }
  • 相关阅读:
    handler之责任链模式
    简单的PL/SQl链接远程ORACLE数据库方法
    An internal error occurred during: "Add Deployment". Container with path org.eclipse.jdt.launching.
    myeclipse非正常关闭处理办法
    jQuery Plugin Poshy Tip 使用 统一提示信息
    myeclipse部署maven时,src/main/resources里面配置文件加载不到webapp下classes路径下的问题
    CSS实现背景透明,文字不透明,兼容所有浏览器
    @SuppressWarnings注解
    @GeneratorValue与@GenericGenerator注解使用心得
    jap的教程
  • 原文地址:https://www.cnblogs.com/shangyu/p/3691981.html
Copyright © 2011-2022 走看看