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

可以类似分数规划的做,二分密度,然后转化为最大权闭合子图做,判断是否大于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.
View Code

 

posted on 2015-06-20 15:00  acphile  阅读(187)  评论(0编辑  收藏  举报