zoukankan      html  css  js  c++  java
  • BZOJ1934: [Shoi2007]Vote 善意的投票

    1934: [Shoi2007]Vote 善意的投票

    Time Limit: 1 Sec  Memory Limit: 64 MB
    Submit: 1076  Solved: 660
    [Submit][Status]

    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

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

    Source

    题解:
    这题怎么这么神!
    膜拜hzwer的题解:
    构建源S,汇T
    然后S->一开始投同意的xpy,一开始投反对票的xpy ->T
    流量均为1
    然后对于一个朋友关系(a,b) 添加双向边,流量依然为1
    最后割即为冲突数
    (1) 冲突数不大于 n:
    很显然,哪怕所有xpy之间都存在朋友关系,xpy可以通过改变(或不改变)原先的决定到达全“同意”或全“否定”,那么朋友之间的冲突数为0,而未被自己先前决定的冲突数不大于n
    (2) “同意”集合和“否定”集合之间的边全部是朋友关系
    (3) 冲突是同意与不同意之间的割
    代码:
      1 const inf=maxlongint;
      2 type node=record
      3      from,go,next,v:longint;
      4      end;
      5 var  tot,i,j,n,m,maxflow,l,r,s,t,x,y:longint;
      6      h,head,q,cur:array[0..1000] of longint;
      7      e:array[0..200000] of node;
      8      function min(x,y:longint):longint;
      9       begin
     10       if x<y then exit(x) else exit(y);
     11       end;
     12 procedure ins(x,y,z:longint);
     13  begin
     14  inc(tot);
     15  e[tot].from:=x;e[tot].go:=y;e[tot].v:=z;e[tot].next:=head[x];head[x]:=tot;
     16  end;
     17 procedure insert(x,y,z:longint);
     18  begin
     19  ins(x,y,z);ins(y,x,0);
     20  end;
     21 function bfs:boolean;
     22  var i,x,y:longint;
     23  begin
     24  fillchar(h,sizeof(h),0);
     25  l:=0;r:=1;q[1]:=s;h[s]:=1;
     26  while l<r do
     27   begin
     28   inc(l);
     29   x:=q[l];
     30   i:=head[x];
     31   while i<>0 do
     32    begin
     33    y:=e[i].go;
     34    if (e[i].v<>0) and (h[y]=0) then
     35     begin
     36      h[y]:=h[x]+1;
     37      inc(r);q[r]:=y;
     38     end;
     39    i:=e[i].next;
     40    end;
     41   end;
     42  exit (h[t]<>0);
     43  end;
     44 function dfs(x,f:longint):longint;
     45  var i,y,used,tmp:longint;
     46  begin
     47  if x=t then exit(f);
     48  used:=0;
     49  i:=cur[x];
     50  while i<>0 do
     51   begin
     52   y:=e[i].go;
     53   if (h[y]=h[x]+1) and (e[i].v<>0) then
     54    begin
     55    tmp:=dfs(y,min(e[i].v,f-used));
     56    dec(e[i].v,tmp);if e[i].v<>0 then cur[x]:=i;
     57    inc(e[i xor 1].v,tmp);
     58    inc(used,tmp);
     59    if used=f then exit(f);
     60    end;
     61   i:=e[i].next;
     62   end;
     63  if used=0 then h[x]:=-1;
     64  exit(used);
     65  end;
     66 procedure dinic;
     67  begin
     68  while bfs do
     69   begin
     70   for i:=s to t do cur[i]:=head[i];
     71   inc(maxflow,dfs(s,inf));
     72   end;
     73  end;
     74 procedure init;
     75  begin
     76  tot:=1;
     77  readln(n,m);
     78  s:=0;t:=n+1;
     79  for i:=1 to n do
     80   begin
     81   read(x);
     82   if x=0 then insert(s,i,1)
     83   else insert(i,t,1);
     84   end;
     85  readln;
     86  for i:=1 to m do begin readln(x,y);insert(x,y,1);insert(y,x,1);end;
     87  end;
     88 procedure main;
     89  begin
     90  maxflow:=0;
     91  dinic;
     92  writeln(maxflow);
     93  end;
     94 begin
     95  assign(input,'input.txt');assign(output,'output.txt');
     96  reset(input);rewrite(output);
     97  init;
     98  main;
     99  close(input);close(output);
    100 end.       
    View Code
  • 相关阅读:
    hdu 3951 Coin Game
    hdu 1273 漫步森林
    hdu 2082 找单词
    kmp算法(模板)
    CodeForces 742B Arpa’s obvious problem and Mehrdad’s terrible solution
    大二上每日总结
    大二上每日总结
    大二上每日总结
    大二上学期周总结
    大二上每日总结
  • 原文地址:https://www.cnblogs.com/zyfzyf/p/3908343.html
Copyright © 2011-2022 走看看