• 《hdu2819》


    看到题目想了一会感觉就是二分图的方向,但是这个图的建模抽象了好久。

    后面我直接对等于1的行列连边,就发现了这样连边是合法的。且需要明白的是交换行的操作实际上是和交换列等价的,所以我们只需要去交换列判断是否成立即可

    对于每个行i,我们要找到一列能使他这一行的第i列为1,那么仔细思考之后发现,其实就是找到的这一列和第i列交换。

    然后就可以建图去匹配了。

    这里还有一个麻烦的地方,就是在一次交换之后,可能已经改变了原有的行列。

    这时候需要转移匹配。

    也就是说,如果当前为1 匹配 4,4 匹配 2.

    那么在第一次交换1,4后1的匹配应该变成2,而4的匹配应该变成4.

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    typedef pair<int,int> pii;
    const int N = 5e6 + 5;
    const LL Mod = 1e9 + 7;
    #define INF 1e9
    #define dbg(x) cout << "now this num is " << x << endl;
    inline LL read()
    {
        LL x = 0,f = 1;char c = getchar();
        while(c < '0' || c > '9'){if(c == '-') f = -1;c = getchar();}
        while(c >= '0' && c <= '9'){x = (x << 1) + (x << 3) + (c ^ 48);c = getchar();}
        return x * f;
    }
    int n,match[105],vis[105];
    vector<int> G[105];
    bool Find(int x)
    {
        for(auto v : G[x])
        {
            if(vis[v]) continue;
            vis[v] = 1;
            if(match[v] == -1 || Find(match[v]))
            {
                match[v] = x;
                return true;
            }
        }
        return false;
    }
    bool solve()
    {
        int ans = 0;
        memset(match,-1,sizeof(match));
        for(int i = 1;i <= n;++i)
        {
            memset(vis,0,sizeof(vis));
            if(Find(i)) ans++;
        }
        return ans == n;
    }
    int main()
    {
        while(~scanf("%d",&n))
        {
            for(int i = 1;i <= n;++i) G[i].clear();
            for(int i = 1;i <= n;++i)
                for(int j = 1;j <= n;++j)
                {
                    int x;x = read();
                    if(x == 1) G[i].push_back(j);
                }
            if(solve())
            {
                vector<pii> vec;
                for(int i = 1;i <= n;++i)
                {
                    if(i != match[i])
                    {
                        for(int j = 1;j <= n;++j)
                        {
                            if(match[j] == i)
                            {
                                vec.push_back(pii{i,j});
                                swap(match[i],match[j]);
                                break;
                            }
                        }
                    }
                }
                printf("%d
    ",vec.size());
                for(int i = 0;i < vec.size();++i) printf("C %d %d
    ",vec[i].first,vec[i].second);
            }
            else printf("-1
    ");
        }
        return 0;
    }
    View Code
  • 相关阅读:
    区块链
    区块链
    区块链
    区块链
    区块链 – 介绍
    区块链 教程
    Matplotlib 直方图
    Matplotlib 饼图
    Matplotlib 柱状图
    Matplotlib 多个图形
  • 原文地址:https://www.cnblogs.com/zwjzwj/p/13925836.html
Copyright © 2020-2023  润新知