首页 > 代码库 > WIKIOI 1222信与信封问题
WIKIOI 1222信与信封问题
题目描述 Description
John先生晚上写了n封信,并相应地写了n个信封将信装好,准备寄出。但是,第二天John的儿子Small John将这n封信都拿出了信封。不幸的是,Small John无法将拿出的信正确地装回信封中了。
将Small John所提供的n封信依次编号为1,2,…,n;且n个信封也依次编号为1,2,…,n。假定Small John能提供一组信息:第i封信肯定不是装在信封j中。请编程帮助Small John,尽可能多地将信正确地装回信封。
输入描述 Input Description
n文件的第一行是一个整数n(n≤100)。信和信封依次编号为1,2,…,n。
n接下来的各行中每行有2个数i和j,表示第i封信肯定不是装在第j个信封中。文件最后一行是2个0,表示结束。
输出描述 Output Description
输出文件的各行中每行有2个数i和j,表示第i封信肯定是装在第j个信封中。请按信的编号i从小到大顺序输出。若不能确定正确装入信封的任何信件,则输出“none”。
样例输入 Sample Input
3
1 2
1 3
2 1
0 0
样例输出 Sample Output
1 1
数据范围及提示 Data Size & Hint
题解:(摘抄)
典型的二分图最大匹配匈牙利算法
若完美匹配中一条边必须存在, 那如果删掉这条边就不会存在完美匹配
代码:
1 var px,py:array[0..100] of longint; 2 map:array[0..100,0..100] of boolean; 3 i,n,op,t,x,y,ans:longint; 4 vis:array[0..100] of longint; 5 flag:boolean; 6 function find(x:longint):boolean; 7 var i:longint; 8 begin 9 for i:=1 to n do10 if map[x,i] then11 begin12 if (vis[i]=t) then continue;13 vis[i]:=t;14 if (py[i]=0) or (find(py[i])) then15 begin16 py[i]:=x;17 px[x]:=i;18 exit(true);19 end;20 end;21 exit(false);22 end;23 procedure init;24 begin25 readln(n);26 readln(x,y);27 fillchar(map,sizeof(map),true);28 while (x<>0) and (y<>0) do29 begin30 map[x,y]:=false;31 readln(x,y);32 end;33 end;34 procedure main;35 begin36 for i:=1 to n do37 begin38 t:=i;39 if (find(i)) then inc(ans);40 end;41 if ans<>n then writeln(‘none‘)42 else43 begin44 flag:=false;45 fillchar(vis,sizeof(vis),0);46 for i:=1 to n do47 begin48 t:=i;49 op:=px[i];50 map[i,op]:=false;51 py[op]:=0;px[i]:=0;52 if not(find(i)) then53 begin54 writeln(i,‘ ‘,op);55 px[i]:=op;56 py[op]:=i;57 flag:=true;58 end;59 map[i,op]:=true;60 end;61 if not(flag) then writeln(‘none‘);62 end;63 end;64 begin65 init;66 main;67 end.
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。