Luogu P1129 Problem Solving Report

Topic description

Little $Q$ is a very smart kid. Besides chess, he also likes to play a computer puzzle game - matrix game. Matrix games are played on an $N*N$ black and white square (like chess, except that the colors are arbitrary). Two operations can be performed on this matrix at a time:

Row swap operation: select any two rows of the matrix and swap the two rows (that is, swap the colors of the corresponding grids)

Column exchange operation: select any two columns of the matrix and exchange the two columns (that is, exchange the color of the corresponding grid)

The goal of the game is to make the squares on the main diagonal (the line connecting the upper left corner to the lower right corner) of the square matrix all black through several operations.

For some levels, Xiao $Q$ was so puzzled that he began to wonder if these levels were completely unsolvable! ! So little $Q$ decided to write a program to determine whether these levels have solutions.

Input and output format

Input format:

The first line contains an integer $T$ representing the number of groups of data.

Next, it contains $T$ groups of data, the first row of each group of data is an integer $N$, indicating the size of the square matrix; the next $N$ row is a $N*N$ $01$ matrix ($0$ represents white, $1 $ means black).

Output format:

Contains the $T$ line. For each set of data, if the level has a solution, output a line of $Yes$; otherwise, output a line of $No$.

illustrate

For $20$% of data, $N ≤ 7$

For $50$% of data, $N ≤ 50$

For $100$% of data, $N ≤ 200$


Studying operations and requirements, we can convert this: each row has at least one $1$ and these $1$ are not in the same column as each other

For row $i$, we used the $1$ of the coordinate $(i,j)$, so isn't the $1$ of the $j$ column abolished?

OK, let's find a match.

The point with coordinates $(i,j)$ is used as the edge of row $i$ and column $j$.

Find the maximum number of matches for each row and column.

Bipartite graph matching.


code:

#include <cstdio>
#include <cstring>
const int N=202;
struct Edge
{
    int to,next;
}g[N*N];
int T,head[N],cnt=0,n;

void add(int u,int v)
{
    g[++cnt].to=v,g[cnt].next=head[u],head[u]=cnt;
}
int match[N],used[N];
bool m_match(int now)
{
    for(int i=head[now];i;i=g[i].next)
    {
        int v=g[i].to;
        if(!used[v])
        {
            used[v]=1;
            if(!match[v]||m_match(match[v]))
            {
                match[v]=now;
                return true;
            }
        }
    }
    return false;
}

int main()
{
    scanf("%d",&T);
    int is;
    while(T--)
    {
        memset(match,0,sizeof(match));
        memset(head,0,sizeof(head));
        scanf("%d",&n);cnt=0;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
            {
                scanf("%d",&is);
                if(is) add(i,j);
            }
        int ans=0;
        for(int i=1;i<=n;i++)
        {
            memset(used,0,sizeof(used));
            if(m_match(i)) ans++;
        }
        if(ans==n) printf("Yes\n");
        else printf("No\n");
    }
}

Some of my errors appearing in detail:

  1. Hungarian used array is set to true timing (seems often wrong)
  2. The timing when used is set to 0 (outside of if)
  3. Forward star head, cnt set to 0

2018.5.5

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325344044&siteId=291194637