Alice and Bob meet again. This time they play a game named MATRIX TRANSFORMER.
They got an n * n board. Every grid has two positions, UP and DOWN. In this game you can push some amazing buttons to exchange any two rows or any two columns. Alice will win if she got the grids in the main diagonal line all UP.
But Alice finds that for some board, no matter how many times she tries, she cannot get the grids in the main diagonal line all UP. Now she asks you for help, tell her if she can win this board or not.
Input
There are several test cases.
For each test case:
The 1st line contains 1 integer n, indicating the size of the board. (1 ≤ n ≤ 200)
The next n lines, each contains n characters. 'U' indicates the position UP, and 'D' indicates the position DOWN.
There is no separation line between any two test cases.
Output
For each test case, you should print one line. You should print 'YES' if Alice can win, print 'NO' if not.
Sample Input
3 DUD UDD DDU 3 DUD DUD UDD
Sample Output
YES NO
题意:给出n*n矩阵,能移动任意两行或两列,求经过移动后主对角线上的字母能不能都是‘U'。
思路;第一次做这道题时还没学二分图,想破头脑还没想出来,学完二分图后回来做这道题,原来就是那么简单的二分图最大匹配。所有的行0,1...n-1为二分图的一分,所有的列0,1...n-1为二分图的另一分,让'U'的行num和列num连线,依题意,任意行或任意列都可以交换num,
所以如果二分图的最大匹配为n时,经交换后能使所有i属于0,1...n且行i和列i连线,即’U'在(i,i)上。(第一次写博客,二分图最大匹配模板为挑战书里的)
#include <iostream> #include <cstdio> #include <algorithm> #include <cmath> #include <cstring> #include <queue> #include <stack> using namespace std; vector<int> g[409]; int match[409]; bool used[409]; char s[209][209]; int n; void add_edge(int u, int v) { g[v].push_back(u); g[u].push_back(v); } int dfs(int v) { used[v]=true; for(int i=0; i<g[v].size(); i++) { int u=g[v][i], w=match[u]; if(w<0 || !used[w] && dfs(w)) { match[u]=v; match[v]=u; return true; } } return false; } int bipartite_matching() { int res=0; memset(match, -1, sizeof(match)); for(int v=0; v<n+n; v++) { if(match[v]<0) { memset(used, 0, sizeof(used)); if(dfs(v)) res++; } } return res; } int main() { while(~scanf("%d", &n)) { for(int i=0; i<409; i++) g[i].clear(); for(int i=0; i<n; i++) scanf(" %s", s[i]); for(int i=0; i<n; i++) { for(int j=0; j<n; j++) { if(s[i][j]=='U') { add_edge(i, j+n); } } } if(bipartite_matching()==n) printf("YES\n"); else printf("NO\n"); } }