1934: [Shoi2007]Vote 善意的投票 - BZOJ

Description
幼儿园里有n个小朋友打算通过投票来决定睡不睡午觉。对他们来说,这个问题并不是很重要,于是他们决定发扬谦让精神。虽然每个人都有自己的主见,但是为了照顾一下自己朋友的想法,他们也可以投和自己本来意愿相反的票。我们定义一次投票的冲突数为好朋友之间发生冲突的总数加上和所有和自己本来意愿发生冲突的人数。 我们的问题就是,每位小朋友应该怎样投票,才能使冲突数最小?
Input
第一行只有两个整数n,m,保证有2≤n≤300,1≤m≤n(n-1)/2。其中n代表总人数,m代表好朋友的对数。文件第二行有n个整数,第i个整数代表第i个小朋友的意愿,当它为1时表示同意睡觉,当它为0时表示反对睡觉。接下来文件还有m行,每行有两个整数i,j。表示i,j是一对好朋友,我们保证任何两对i,j不会重复。
Output
只需要输出一个整数,即可能的最小冲突数。
Sample Input
3 3
1 0 0
1 2
1 3
3 2
Sample Output
1
HINT

在第一个例子中,所有小朋友都投赞成票就能得到最优解

 

经典的最小割模型,见算法合集之《最小割模型在信息学竞赛中的应用》.pdf

本来的意愿就是固定的点,然后每个都是不确定的点

从s向固定的0连容量inf的边,从固定的1向t连容量inf的边

从固定的0向自己对应的节点连容量1的边,从对应的节点向固定的1连容量1的边

朋友之间就互相连容量1的边

很囧的建错了两次图

1.固定的点我只连了容量1的边

2.固定的0和1向每个节点都连了边

但是有90分,应该是因为每个人都选同一种代价小于n吧(这个90分好奇葩的样子)

 1 const
 2         maxn=610;
 3         inf=1000000;
 4 var
 5         map:array[0..maxn,0..maxn]of longint;
 6         n,m,s,t:longint;
 7 
 8 procedure init;
 9 var
10         i,x,y:longint;
11 begin
12         read(n,m);
13         s:=0;
14         t:=n*2+1;
15         for i:=1 to n do
16           begin
17             read(x);
18             if x=0 then
19               begin
20                 map[s,i+n]:=inf;
21                 map[i+n,i]:=1;
22               end
23             else
24               begin
25                 map[i+n,t]:=inf;
26                 map[i,i+n]:=1;
27               end;
28           end;
29         for i:=1 to m do
30           begin
31             read(x,y);
32             map[x,y]:=1;
33             map[y,x]:=1;
34           end;
35 end;
36 
37 var
38         dis,vh,pre,his:array[0..maxn]of longint;
39         flow,aug:longint;
40 
41 procedure sap;
42 var
43         i,j,min:longint;
44         flag:boolean;
45 begin
46         vh[0]:=t+1;
47         i:=s;
48         aug:=inf;
49         while dis[i]<=t do
50           begin
51             his[i]:=aug;
52             flag:=false;
53             for j:=s to t do
54               if (map[i,j]>0) and (dis[i]=dis[j]+1) then
55               begin
56                 flag:=true;
57                 if aug>map[i,j] then aug:=map[i,j];
58                 pre[j]:=i;
59                 i:=j;
60                 if i=t then
61                 begin
62                   inc(flow,aug);
63                   while i<>s do
64                     begin
65                       inc(map[i,pre[i]],aug);
66                       dec(map[pre[i],i],aug);
67                       i:=pre[i];
68                     end;
69                   aug:=inf;
70                 end;
71                 break;
72               end;
73             if flag then continue;
74             min:=t;
75             for j:=s to t do
76               if (map[i,j]>0) and (dis[j]<min) then min:=dis[j];
77             dec(vh[dis[i]]);
78             if vh[dis[i]]=0 then break;
79             dis[i]:=min+1;
80             inc(vh[min+1]);
81             if i<>s then
82             begin
83               i:=pre[i];
84               aug:=his[i];
85             end;
86           end;
87         writeln(flow);
88 end;
89 
90 begin
91         init;
92         sap;
93 end.
View Code

 

posted @ 2014-04-24 21:59  Randolph87  阅读(260)  评论(0编辑  收藏  举报