0
点赞
收藏
分享

微信扫一扫

POJ1719行列匹配

時小白 2022-07-27 阅读 21

题意:
     给一个n*m的格子,每一列都有两个白色的,其余的全是黑色的,然后要选择m个格子,要求是每一列必须也只能选一个,而每一行至少选择一个,输出一种可行的方案没,输出的格式是输出m个数,表示每一列上选了第几行的数。


思路: 
     一开始看到每一行至少选择一个,都点蒙了,后来自己画了下,哎!SB了,比较简单的题目,题目的输入数据是说n<=m,那么也就是指存在两种情况,n=m和n<m,当n=m的时候就是每一行每一列至少也只能选一个,直接匹配就行了,而当n<m的时候也就是说每一个行至少一个,有的比一个多,那么我们就先用二分匹配给每一行都安排一个,然后剩下的没有安排的列,我们只要随便给挑一个就行了。

#include<stdio.h>

#include<string.h>



#define N_node 1000 + 10

#define N_edge 2000 + 20



typedef struct

{

int to ,next;

}STAR;



typedef struct

{

int a ,b;

}NODE;



STAR E[N_edge];

NODE node[N_node];

int list[N_node] ,tot;

int mkgx[N_node] ,mkdfs[N_node];



void add(int a ,int b)

{

E[++tot].to = b;

E[tot] .next = list[a];

list[a] = tot;

}



int DFS_XYL(int x)

{

for(int k = list[x] ;k ;k = E[k].next)

{

int to = E[k].to;

if(mkdfs[to]) continue;

mkdfs[to] = 1;

if(mkgx[to] == -1 || DFS_XYL(mkgx[to]))

{

mkgx[to] = x;

return 1;

}

}

return 0;

}



int main ()

{

int t ,n ,m ,i ,j;

scanf("%d" ,&t);

while(t--)

{

scanf("%d %d" ,&n ,&m);

memset(list ,0 ,sizeof(list));

for(i = 1 ;i <= m ;i ++)

{

scanf("%d %d" ,&node[i].a ,&node[i].b);

add(node[i].a ,i);

add(node[i].b ,i);

}

int Ans = 0;

memset(mkgx ,255 ,sizeof(mkgx));

for(i = 1 ;i <= n ;i ++)

{

memset(mkdfs ,0 ,sizeof(mkdfs));

Ans += DFS_XYL(i);

}

if(Ans < n)

{

printf("NO\n");

continue;

}

for(i = 1 ;i <= m ;i ++)

{

if(mkgx[i] == -1) Ans = node[i].a;

else Ans = mkgx[i];

if(i == m) printf("%d\n" ,Ans);

else printf("%d " ,Ans);

}

}

return 0;

}








举报

相关推荐

0 条评论