zoukankan      html  css  js  c++  java
  • 一般图最大匹配--带花树

    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    
    const double esp = 1e-8;
    #define Fact(x) ((x)*(x))
    //一般图匹配带花树
    const int MaxN = 111;
    int N;
    bool Graph[MaxN][MaxN];
    int Match[MaxN];
    bool InQueue[MaxN], InPath[MaxN], InBlossom[MaxN];
    int Head, Tail;
    int Queue[MaxN];
    int Start, Finish;
    int NewBase;
    int Father[MaxN], Base[MaxN];
    int Count;
    void CreateGraph()
    {
        int u, v;
        memset(Graph,false,sizeof(Graph));
        scanf("%d", &N);
        while( scanf("%d", &N) );
        while( scanf("%d%d", &u,&v) != EOF )
            Graph[u][v] = Graph[v][u] = true;
    }
    
    void Push(int u)
    {
        Queue[Tail] = u;
        Tail ++;
        InQueue[u] = true;
    }
    int Pop()
    {
        int res = Queue[Head];
        Head++;
        return res;
    }
    int FindCommonAncestor(int u,int v)
    {
        memset( InPath, false, sizeof(InPath));
        while( true )
        {
            u = Base[u];
            InPath[u] = true;
            if( u == Start ) break;
            u = Father[ Match[u] ];
        }
        while( true )
        {
            v = Base[v];
            if( InPath[v] ) break;
            v = Father[ Match[v] ];
        }
        return v;
    }
    void ResetTrace(int u)
    {
        int v;
        while( Base[u] != NewBase )
        {
            v = Match[u];
            InBlossom[ Base[u] ] = InBlossom[ Base[v] ] = true;
            u = Father[v];
            if( Base[u] != NewBase ) Father[u] = v;
        }
    }
    void BlossomContract(int u,int v)
    {
        NewBase = FindCommonAncestor(u,v);
        memset( InBlossom, false, sizeof(InBlossom ));
        ResetTrace(u);
        ResetTrace(v);
        if( Base[u] != NewBase ) Father[u] = v;
        if( Base[v] != NewBase ) Father[v] = u;
        for(int tu = 1; tu <= N; tu++)
            if( InBlossom[Base[tu]] )
            {
                Base[tu] = NewBase;
                if( !InQueue[tu] ) Push(tu);
            }
    }
    void FindAugmentingPath()
    {
        memset(InQueue,false,sizeof(InQueue));
        memset(Father,0,sizeof(Father));
        for(int i = 1; i <= N; i++)
            Base[i] = i;
        Head = Tail = 1;
        Push( Start );
        Finish = 0;
        while( Head < Tail )
        {
            int u = Pop();
            for(int v = 1; v <= N; v++)
                if( Graph[u][v] && (Base[u]!=Base[v]) && (Match[u]!=v) )
                {
                    if( (v==Start) ||
                       ( (Match[v]>0)&&(Father[Match[v]]>0) ) )
                        BlossomContract(u,v);
                    else if( Father[v] == 0 )
                    {
                        Father[v] = u;
                        if( Match[v] > 0 )
                            Push(Match[v]);
                        else
                        {
                            Finish = v;
                            return;
                        }
                    }
                }
        }
    }
    void AugmentPath()
    {
        int u, v, w;
        u = Finish;
        while( u > 0 )
        {
            v = Father[u];
            w = Match[v];
            Match[v] = u;
            Match[u] = v;
            u = w;
        }
    }
    void Edmonds()
    {
        memset( Match,0,sizeof(Match));
        for(int u = 1; u <= N; u++)
        {
            if( Match[u] == 0 )
            {
                Start = u;
                FindAugmentingPath();
                if( Finish > 0 ) AugmentPath();
            }
        }
    }
    
    void PrintMatch(){
        Count = 0;
        for(int u = 1; u <= N; u++)
            if( Match[u] > 0 )
                Count++;
        printf("%d
    ", Count );
        for(int u = 1; u <= N; u++)  
            if( u < Match[u] )
            printf("%d %d
    ", u, Match[u] );
    }
    
    
    struct Point{
        int x, y;
        Point(){}
        Point(int _x,int _y):x(_x),y(_y){}
        Point operator - (const Point &b)const{
            return Point(x-b.x,y-b.y);
        }
        int operator * (const Point &b)const{
            return x*b.y-b.x*y;
        }
        double operator &(const Point &b)const{
            return x*b.x+y*b.y;
        }
    };
    struct Line{
        Point s, e;
        double k;
        Line(){}
        Line(Point _s,Point _e){
            s = _s; e = _e;
        }
    };
    int sign(double x){ return x<-esp?-1:(x>esp);}
    double dist(Point a,Point b) {
        return sqrt( Fact(a.x-b.x) + Fact(a.y-b.y) );
    }
    bool inter(Line l1, Line l2)
    {
        return
        max(l1.s.x,l1.e.x) >= min( l2.s.x,l2.e.x) &&
        max(l2.s.x,l2.e.y) >= min( l1.s.x,l1.e.x) &&
        max(l1.s.y,l1.e.y) >= min( l2.s.y,l2.e.y) &&
        max(l2.s.y,l2.e.y) >= min( l1.s.y,l1.e.y) &&
        sign( (l2.s-l1.s)*(l1.e-l1.s) )*sign( (l2.e-l1.s)*(l1.e-l1.s) ) <= 0 &&
        sign( (l1.s-l2.s)*(l2.e-l2.s) )*sign( (l1.e-l2.s)*(l2.e-l2.s) ) <= 0;
    }
    
    
    void gao(){
        CreateGraph();
        Edmonds();
        PrintMatch();
    }
  • 相关阅读:
    03.部署 kubectl 命令行工具
    02.创建 CA 证书和秘钥
    01.组件版本和集群环境
    23.kubernetes 组件版本和配置策略
    22.Kubernetes Ingress: HTTP 7层路由机制
    Python程序中#-*-coding: UTF-8 -*-的作用
    Python程序中首行#!/usr/bin/env python的作用
    mac install php dev
    linux的nohup disown setsid screen
    linux 常用查找命令 小技巧
  • 原文地址:https://www.cnblogs.com/yefeng1627/p/3211103.html
Copyright © 2011-2022 走看看