zoukankan      html  css  js  c++  java
  • P1129 [ZJOI2007]矩阵游戏

    传送门

     二分图

    匈牙利算法

    重要的是怎么建图(怎么看都不像二分图....)

    仔细看还是能发现的..

    两个操作不管怎么搞,在同一行的永远在同一行同一行的 1 想怎么左右换都可以

    所以根本不用上下交换(如果下面没有1,换了以后上面就没有1了)

    题目要让对角线上的每个点都有1

    就是把对角线的点与 1 匹配

    因为是对角线的点,所以可以发现:在矩阵中,如果这一有一个 1 已经匹配了

    那么这一列其他的 1 都不能与其他点匹配 ( 发现了吗,二分图中每个点同时也只能匹配一个点 )

    所以把一列的看成一个点,与每行唯一需要匹配的点匹配(同样的,因为每行唯一所以也看成一个点)

    如果要匹配,那么两个点必须要在同一行(显然...)

    那么图就出来了,n 个对角线的点,n 列缩成 n 个点

    如果第 i 行的第 j 列是 1,那么连一条从 i 到 j 的边

    最后跑一遍模板就好了

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    using namespace std;
    const int N=100005;//数组可以开大点,最近因为数组大小不够死了很多次...
    int t,n,tot;
    int fir[N],from[N],to[N],cnt;
    inline void add(int a,int b)
    {
        from[++cnt]=fir[a];
        fir[a]=cnt;
        to[cnt]=b;
    }
    int match[N];
    bool vis[N];
    inline bool dfs(int x)
    {
        for(int i=fir[x];i;i=from[i])
        {
            int u=to[i];
            if(vis[match[u]]) continue;
            vis[match[u]]=1;
            if((!match[u])||dfs(match[u]))
            {
                match[u]=x;
                return 1;
            }
        }
        return 0;
    }//以上为匈牙利模板
    inline void Clear()
    {
        memset(match,0,sizeof(match));
        memset(fir,0,sizeof(fir));
        memset(from,0,sizeof(from));
        memset(to,0,sizeof(to));
        cnt=0; tot=0;
    }//有多组数据,每次都要初始化
    int main()
    {
        int a;
        cin>>t;
        while(t--)
        {
            Clear();
            scanf("%d",&n);
            for(int i=1;i<=n;i++)
                for(int j=1;j<=n;j++)
                {
                    scanf("%d",&a);
                    if(a)
                        add(i,j);
                }//建图
            bool flag=0;
            for(int i=1;i<=n;i++)
            {
                memset(vis,0,sizeof(vis));
                if(!dfs(i))
                {
                    flag=1;
                    break;
                }
            }
            if(flag) cout<<"No"<<endl;
            else cout<<"Yes"<<endl;
        }
        return 0;
    }
  • 相关阅读:
    springboot 入门
    json-lib 的 maven dependency 引入及Jar包下载
    DataGridView 使用技巧精华
    SqlServer无备份下误删数据恢复
    Reflector 已经out了,试试ILSpy
    C# 反射,动态编译
    windows8和windows server2012不联网安装.net 3.5(包括2.0和3.0)
    如何附加被分离的质疑数据库? [转]
    easyui validatebox 验证类型
    所见即所得:七大无需编程的DIY开发工具
  • 原文地址:https://www.cnblogs.com/LLTYYC/p/9529533.html
Copyright © 2011-2022 走看看