bzoj1312

忘写题解了,经典的最大密度子图

可以类似分数规划的做,二分密度,然后转化为最大权闭合子图做,判断是否大于0

注意方案的输出

  1 const eps=1e-6;
  2       lim=1e-12;
  3       inf=1000000007;
  4 type node=record
  5        po,next:longint;
  6        flow:double;
  7      end;
  8
  9 var e:array[0..800010] of node;
 10     numh,h,cur,pre,p,x,y:array[0..2010] of longint;
 11     v:array[0..2010] of boolean;
 12     d:array[0..2010] of double;
 13     len,i,n,m,t,ans:longint;
 14     l,r,mid:double;
 15
 16 function min(a,b:double):double;
 17   begin
 18     if a>b then exit(b) else exit(a);
 19   end;
 20
 21 procedure add(x,y:longint;f:double);
 22   begin
 23     inc(len);
 24     e[len].po:=y;
 25     e[len].flow:=f;
 26     e[len].next:=p[x];
 27     p[x]:=len;
 28   end;
 29
 30 procedure build(x,y:longint;f:double);
 31   begin
 32     add(x,y,f);
 33     add(y,x,0);
 34   end;
 35
 36 function sap:double;
 37   var u,i,j,tmp,q:longint;
 38       neck:double;
 39   begin
 40     fillchar(numh,sizeof(numh),0);
 41     fillchar(h,sizeof(h),0);
 42     numh[0]:=t+1;
 43     u:=0;
 44     sap:=0;
 45     neck:=inf;
 46     for i:=0 to t do
 47       cur[i]:=p[i];
 48
 49     while h[0]<t+1 do
 50     begin
 51       d[u]:=neck;
 52       i:=cur[u];
 53       while i<>-1 do
 54       begin
 55         j:=e[i].po;
 56         if (e[i].flow>lim) and (h[u]=h[j]+1) then
 57         begin
 58           neck:=min(neck,e[i].flow);
 59           pre[j]:=u;
 60           cur[u]:=i;
 61           u:=j;
 62           if u=t then
 63           begin
 64             sap:=sap+neck;
 65             while u<>0 do
 66             begin
 67               u:=pre[u];
 68               j:=cur[u];
 69               e[j].flow:=e[j].flow-neck;
 70               e[j xor 1].flow:=e[j xor 1].flow+neck;
 71             end;
 72             neck:=inf;
 73           end;
 74           break;
 75         end;
 76         i:=e[i].next;
 77       end;
 78       if i=-1 then
 79       begin
 80         dec(numh[h[u]]);
 81         if numh[h[u]]=0 then break;
 82         q:=-1;
 83         tmp:=t;
 84         i:=p[u];
 85         while i<>-1 do
 86         begin
 87           j:=e[i].po;
 88           if e[i].flow>lim then
 89             if h[j]<tmp then
 90             begin
 91               q:=i;
 92               tmp:=h[j];
 93             end;
 94           i:=e[i].next;
 95         end;
 96         h[u]:=tmp+1;
 97         inc(numh[h[u]]);
 98         cur[u]:=q;
 99         if u<>0 then
100         begin
101           u:=pre[u];
102           neck:=d[u];
103         end;
104       end;
105     end;
106   end;
107
108 function dfs(x:longint):boolean;
109   var i,y:longint;
110   begin
111     if x=t then exit(true);
112     i:=p[x];
113     v[x]:=true;
114     while i<>-1 do
115     begin
116       y:=e[i].po;
117       if (e[i].flow>lim) and not v[y] then
118         if dfs(y) then exit(true);
119       i:=e[i].next;
120     end;
121     exit(false);
122   end;
123
124 function check(w:double):boolean;
125   var i:longint;
126       f:double;
127   begin
128     len:=-1;
129     fillchar(p,sizeof(p),255);
130     for i:=1 to m do
131     begin
132       build(x[i]+m,i,inf);
133       build(y[i]+m,i,inf);
134       build(i,t,1);
135     end;
136     for i:=1 to n do
137       build(0,i+m,w);
138     f:=sap;
139     if m-f>0 then
140     begin
141       ans:=0;
142       for i:=1 to n do
143       begin
144         fillchar(v,sizeof(v),false);
145         if dfs(i+m) then inc(ans);
146       end;
147       exit(true);
148     end;
149     exit(false);
150   end;
151
152 begin
153   readln(n,m);
154   for i:=1 to m do
155     readln(x[i],y[i]);
156   t:=n+m+1;
157   l:=0;
158   r:=m;
159   while l+eps<r do
160   begin
161     mid:=(l+r)/2;
162     if check(mid) then l:=mid
163     else r:=mid;
164   end;
165   if m=0 then ans:=1;  //必须要选
166   writeln(ans);
167 end.

时间: 2024-10-11 17:35:11

bzoj1312的相关文章

Bzoj1312 / POJ3155 Neerc2006 Hard Life

Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 459  Solved: 114 Description 在一家公司中,人事部经理与业务部经理不和.一次,总经理要求人事部从公司的职员中挑选出一些来帮助业务部经理完成一项任务.人事部经理发现,在公司的所有职员中,有一些人相处得很不好.如果把他们同时放在一个工作小组中,他们将会给主管带来不小的麻烦.人事部经理还知道,在一个工作小组中,主管人员的麻烦程度可以认为是(带来麻烦的人的对数/总人数) .于是,人