zoukankan      html  css  js  c++  java
  • 【AT5161】[AGC037D] Sorting a Grid(二分图匹配)

    点此看题面

    • 给定一个(n imes m)的矩阵(A),你可以将(A)每一行任意重排得到(B),将(B)每一列任意重排得到(C),将(C)每一行任意重排得到(D)
    • 要求(D)((i,j))格子上的数是((i-1) imes m+j),求构造一组合法的(B,C)
    • (n,mle100)

    题意转化

    反向考虑,要让最终(D)满足这样的条件,因为(C)(D)只能对于行重排,就需要让每一行的数都正确。

    又由于(B)(C)只能对于列重排,所以(B)的每一列中应该同时包含每种行的元素。

    所以说,给最终第(i)行的元素赋上一个颜色(i),我们的问题就变成了,对(A)进行行重排,让每一列都能包含所有颜色的元素。

    二分图匹配

    经典的二分图匹配问题,对于每个元素,从它所在的行对应的点向它的颜色对应的点连边。

    显然这是一张二分图,而一对完美匹配就意味着一列的填法。

    因此只要跑(m)次匈牙利算法就结束了。

    代码:(O(n^2m^2))

    #include<bits/stdc++.h>
    #define Tp template<typename Ty>
    #define Ts template<typename Ty,typename... Ar>
    #define Reg register
    #define RI Reg int
    #define Con const
    #define CI Con int&
    #define I inline
    #define W while
    #define N 100
    using namespace std;
    int n,m,a[N+5][N+5],p[N+5][N+5],b[N+5][N+5],e[N+5][N+5];
    int s[N+5],vis[N+5];I bool Match(CI x,CI ti) {for(RI i=1;i<=n;++i)//匈牙利算法
    	if(e[x][i]&&vis[i]^ti&&(vis[i]=ti,!s[i]||Match(s[i],ti))) return s[i]=x;return 0;}
    int main()
    {
    	RI i,j;for(scanf("%d%d",&n,&m),i=1;i<=n;++i) for(j=1;j<=m;++j) scanf("%d",&a[i][j]),++e[p[i][j]=(a[i][j]-1)/m+1][i];//记录每行和每种颜色间的边数
    	RI k;for(i=1;i<=m;++i) {for(j=1;j<=n;++j) s[j]=vis[j]=0;for(j=1;j<=n;++j) Match(j,j);//做m次二分图匹配
    		for(j=1;j<=n;++j) for(--e[s[j]][j],k=1;k<=m;++k) if(p[j][k]==s[j]) {b[i][j]=a[j][k],p[j][k]=0;break;}}//求出该列的填法
    	for(i=1;i<=n;putchar('
    '),++i) for(j=1;j<=m;++j) printf("%d ",b[j][i]);for(i=1;i<=m;++i) sort(b[i]+1,b[i]+n+1);//直接输出b,然后给每列排序
    	for(i=1;i<=n;putchar('
    '),++i) for(j=1;j<=m;++j) printf("%d ",b[j][i]);return 0;//输出c
    }
    
    败得义无反顾,弱得一无是处
  • 相关阅读:
    LOJ 6089 小Y的背包计数问题 —— 前缀和优化DP
    洛谷 P1969 积木大赛 —— 水题
    洛谷 P1965 转圈游戏 —— 快速幂
    洛谷 P1970 花匠 —— DP
    洛谷 P1966 火柴排队 —— 思路
    51Nod 1450 闯关游戏 —— 期望DP
    洛谷 P2312 & bzoj 3751 解方程 —— 取模
    洛谷 P1351 联合权值 —— 树形DP
    NOIP2007 树网的核
    平面最近点对(加强版)
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/AT5161.html
Copyright © 2011-2022 走看看