• BZOJ 1059: [ZJOI2007]矩阵游戏


    传送门

    解题思路

    二分图匹配,出现1后让这一行和这一列连边,然后跑一遍匈牙利,判断最后的ans是否等于n。刚开始想复杂了,这样连了后还拆点反着连。。

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    
    using namespace std;
    const int MAXN = 605;
    const int MAXM = MAXN*MAXN;
    
    inline int rd(){
        int x=0,f=1;char ch=getchar();
        while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
        while(isdigit(ch))  {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
        return x*f;
    }
    
    int T,n,a[MAXN][MAXN],ans;
    int match[MAXM<<1];
    int head[MAXM<<1],cnt,k;
    int to[MAXM<<1],nxt[MAXM<<1];
    int vis[MAXM<<1],num;
    
    inline void add(int bg,int ed){
        to[++cnt]=ed,nxt[cnt]=head[bg],head[bg]=cnt;
    }
    
    inline bool dfs(int x){
        for(register int i=head[x];i;i=nxt[i]){
            int u=to[i];
            if(vis[u]==num) continue;
            vis[u]=num;
            if(!match[u] || dfs(match[u])) {
                match[u]=x;
                return true;
            }
        }
        return false;
    }
    
    int main(){
        T=rd();
        while(T--){
            memset(head,0,sizeof(head));
            memset(match,0,sizeof(match));
            n=rd();ans=0;
            for(register int i=1;i<=n;i++)
                for(register int j=1;j<=n;j++){ 
                    scanf("%d",&a[i][j]);
                    if(a[i][j]==1) k++,add(i,j);
                } 
            for(register int i=1;i<=k;i++){
                num++;
                if(dfs(i)) ans++;
            }
            if(ans==n) puts("Yes");
            else puts("No");
        }
        return 0;
    }
  • 相关阅读:
    如何优雅地删除 Linux 中的垃圾文件
    session:
    cookie:
    多对多表结构设计:
    接口测试:
    oracle基本笔记整理
    oracle基本笔记整理
    oracle基本笔记整理
    2016年寒假心得
    2016年寒假心得
  • 原文地址:https://www.cnblogs.com/sdfzsyq/p/9676917.html
Copyright © 2020-2023  润新知