zoukankan      html  css  js  c++  java
  • 图论 —— 二分图的判定及最大匹配

    二分图:可将图中顶点分为两个集合,集合内元素独立。

    判定:至少有两个顶点,若有回路,长度必为偶数。

    染色法判定:从某点开始染色为x(-1或1),遍历其所有相邻节点,若未染色,染为-x,否则判断该点颜色,若为x,该图非二分图,退出;为-X则继续遍历。

    UVA - 10004  Bicoloring

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cmath>
    #include<algorithm>
    #include<string>
    #include<cstring>
    #include<map>
    #include<stack>
    #include<set>
    #include<queue>
    using namespace std;
    typedef long long  ll;
    #define me(x) memset(x, -1, sizeof(x))
    #define mem(x) memset(x, 0, sizeof(x))
    const int MOD = 1e18;
    const int N = 2e5 + 5;
    struct node
    {
        int to, next, w;
    }e[N]; //链式前向星存图
    int head[N];
    int vis[N];
    int n, m, id, f;
    void ini()
    {
        id=0;
        f=0;
        me(head);
        mem(vis);
    }
    void add(int u, int v)
    {
        e[id].to = v;
        e[id].next = head[u];
        head[u] = id++;
    }
    
    
    
    void bfs(int x)
    {
        queue<int> q;
        q.push(x);
        vis[x]=-1;
        while(q.size())
        {
            x=q.front();
            q.pop();
            for(int i=head[x]; ~i; i=e[i].next)
            {
                if(!vis[e[i].to])
                {
                    q.push(e[i].to);
                    vis[e[i].to]=-vis[x];
                }
                else
                {
                    if(vis[e[i].to] == vis[x])
                    {f=1;break;}
                }
            }
            if(f) break;
        }
        return ;
    }
    int main()
    {
        int i, j, k;
        int t;
        while(~scanf("%d", &n))
        {
            if(!n) return 0;
            ini();
            int u, v;
            scanf("%d", &m);
            for(i=0; i<m; i++)
            {
                scanf("%d%d", &u, &v);
                add(u,v);add(v,u);
            }
            bfs(0);
            if(f)
            printf("NOT BICOLORABLE.
    ");
            else printf("BICOLORABLE.
    ");
        }
        return 0;
    }
    View Code

    匹配:边集,集合内的边无公共顶点

    最大匹配:二分图中的最大匹配数,即最大无公共顶点边集。

    增广路:从未匹配边开始,沿未匹配边--匹配边--未匹配边--匹配边--未匹配边--的交替路

    以非匹配边结束,则沿该增广路走匹配数加1

    匈牙利算法思想:一直找增广路,增加匹配数,无增广路时匹配数达到最大

    POJ - 1469 COURSES

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cmath>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<map>
    #include<queue>
    #include<stack>
    #include<list>
    #include<set>
    using namespace std;
    typedef int ll;
    typedef pair<ll,ll> P;
    typedef long double ld;
    #define mem(x) memset(x, 0, sizeof(x))
    #define me(x) memset(x, -1, sizeof(x))
    #define fo(i,n) for(i=0; i<n; i++)
    #define sc(x) scanf("%d", &x)
    #define sca(n,m) scanf("%d%d", &n, &m)
    #define pr(x) printf("%d
    ", x)
    #define pri(x) printf("%d ", x)
    #define lowbit(x) x&-x
    const ll MOD = 1e9 + 7;
    const ll oo = 1e18;
    const ll N = 3e3 + 5;
    vector<ll> ve[N];
    ll vis[N], cy[N];
    ll dfs(ll u)
    {
        for(ll i=0; i<ve[u].size(); i++)
        {
            if(!vis[ve[u][i]])
            {
                vis[ve[u][i]]=1;
                if(!cy[ve[u][i]] || dfs(cy[ve[u][i]])) //找增广路
                {
                    cy[ve[u][i]]=u;
                    return 1;
                }
            }
        }
        return 0;
    }
    int main()
    {
        ll i, j, k;
        ll n, m, t;
        ll x;
        sc(t);
        while(t--)
        {
            sca(n,m);
            for(i=m+1; i<=m+n; i++)
                ve[i].clear();
            mem(cy);
            for(i=m+1; i<=n+m; i++)
            {
                sc(k);
                for(j=0; j<k; j++)
                sc(x),ve[i].push_back(x);
            }
            ll ans=0;
            for(i=m+1; i<=n+m; i++)
            {
                for(j=1; j<=m; j++) vis[j]=0;
                if(dfs(i)) ans++;
            }
            if(ans==n) printf("YES
    ");
            else printf("NO
    ");
        }
    
        return 0;
    }
    View Code
  • 相关阅读:
    二叉树同构
    L1-001 Hello World--java
    关于Hanoi的递归分析
    L1-049 天梯赛座位分配
    1001 害死人不偿命的(3n+1)猜想 && 1005 继续(3n+1)猜想
    L1-046 整除光棍
    L1-043 阅览室
    lambda_Consumer接口
    lambda_Supplier接口
    Veu_v-for
  • 原文地址:https://www.cnblogs.com/op-z/p/11155859.html
Copyright © 2011-2022 走看看