JSOI2008 会议安排
JSOI2008 会议安排
【题目描述】
在高层峰会期间,还安排了许多专题对口重要会议:一个重要的会议将会由A国的M位代表和B国的N位代表参加 (M,N不大于1000,代表用1,2,…,M和1,2,…,N表示)。他们被预先分成K组进行商谈。每组两个人分别来自A国和B国。每个参加会议的代表都至少参加了一组谈判。会议为每一个代表都准备了一个房间。技术人员将会在一些房间之间连上直通电话,一个代表至少要和他的一个谈判对手直接联络。连接一个直通电话的价格是常数。技术人员要用尽量少的花费满足会议的要求。
【输入文件】
第一行是三个用空格隔开的整数M, N和K。下面的K行每行有一对数P1–P2,P1表示A国的代表,P2表示B国的代表。P1和P2之间用空格隔开。
【输出文件】
只有一行,即最少要装的电话的数目。
【输入样例】
3 2 4
1 1
2 1
3 1
3 2
【输出样例】
3
【题目分析】
还是水的不行……
把题目抽象出来,就是在一个二分图中,左边m个点,右边n个点,中间k条边,问最少用几条边覆盖所有的点。
我们尽量每次用一条边覆盖图的两边没有被覆盖的点,然后剩下的点每个点都需要一条额外的边来覆盖,这样就想到了……最大匹配
设最大匹配为P,那么ans=m+n-2*P+P=m+n-P
【代码实现】
Code
1 program tyvj1816;
2 type bian=record
3 y,next:longint;
4 end;
5 var b:array[0..1000000]of bian;
6 g,f:array[0..1000]of longint;
7 v:array[0..1000]of boolean;
8 n,m,i,j,k,tot,x,y,ans:longint;
9 function dfs(s:longint):boolean;
10 var i:longint;
11 begin
12 i:=g[s];
13 while i<>0 do
14 begin
15 if not v[b[i].y] then
16 begin
17 v[b[i].y]:=true;
18 if (f[b[i].y]=0)or dfs(f[b[i].y]) then
19 begin
20 f[b[i].y]:=s;
21 exit(true);
22 end;
23 end;
24 i:=b[i].next;
25 end;
26 exit(false);
27 end;
28 procedure insert(x,y:longint);
29 begin
30 inc(tot);
31 b[tot].y:=y;
32 b[tot].next:=g[x];
33 g[x]:=tot;
34 end;
35 begin
36 readln(m,n,k);
37 for i:=1 to k do
38 begin
39 readln(x,y);
40 insert(x,y);
41 end;
42 for i:=1 to m do
43 begin
44 fillchar(v,sizeof(v),0);
45 if dfs(i) then inc(ans);
46 end;
47 ans:=m+n-ans*2+ans;
48 writeln(ans);
49 end.