#41. 【清华集训2014】矩阵变换

题目链接

//Pro:#41. 【清华集训2014】矩阵变换

//可以转化为稳定婚姻问题
//肯定是要让每次选择的数尽量靠右 
//让行为男生,列上的数为女生
//男生的告白次序为从左到右,女生的好感度最大的男生为它在的位置最靠右的那一行
//那么男生告白失败,就会往右靠,女生选择好感度最大的也是从最右边考虑
//这样匹配下去就可以了 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
using namespace std;

const int N=4e2+5;

inline int read()
{
    char c=getchar();int num=0;
    for(;!isdigit(c);c=getchar());
    for(;isdigit(c);c=getchar())
        num=num*10+c-'0';
    return num;
}

int T,n,m;
int man[N][N],wom[N][N];
int chman[N],chwom[N];
queue<int> que;
inline void solve()
{
    n=read(),m=read();
    for(int i=1,a;i<=n;++i)
    {
        man[i][0]=0;
        for(int j=1;j<=m;++j)
        {
            a=read();
            if(a)
            {
                man[i][++man[i][0]]=a;
                wom[a][i]=j;
            }
        }
    }
    for(int i=1;i<=n;++i)
    {
        que.push(i);
        chman[i]=1;
    }
    int now,to;
    memset(chwom,0,sizeof(chwom));
    while(!que.empty())
    {
        now=que.front(),que.pop();
        to=man[now][chman[now]];
        if(chwom[to]&&wom[to][chwom[to]]>wom[to][now])
        {
            ++chman[now];
            que.push(now);
        }
        else
        {
            if(chwom[to])
                que.push(chwom[to]);
            chwom[to]=now;
        }
    }
    for(int i=1;i<=n;++i)
        cout<<man[i][chman[i]]<<' ';
    puts("");
}

int main()
{
    T=read();
    while(T--)
        solve();
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/lovewhy/p/9633948.html