zoukankan      html  css  js  c++  java
  • bzoj2539

    这道题真的不难,但是细节挺多(具体见程序)
    题目本身而言,显然是个费用流模型(或者写KM)

      1 type node=record
      2        point,next,flow,cost:longint;
      3      end;
      4 
      5 var p,x,y,pre,cur,d:array[0..80] of longint;
      6     v:array[0..80] of boolean;
      7     q:array[0..500010] of longint;
      8     edge:array[0..200010] of node;
      9     a:array[0..80,0..80] of longint;
     10     na:array[0..80] of string[21];
     11     t,n,i,len,j,k:longint;
     12     ef:boolean;
     13     s:string;
     14     ch:char;
     15 
     16 function find(x:string):longint;
     17   var i:longint;
     18   begin
     19     for i:=1 to 2*n do
     20       if na[i]=x then exit(i);
     21   end;
     22 
     23 function check(l,r:longint):boolean;
     24   var i:longint;
     25   begin
     26     for i:=1 to 2*n do
     27       if (i<>l) and (i<>r) then
     28         if ((x[i]<=x[l]) and (x[i]>=x[r])) or ((x[i]>=x[l]) and (x[i]<=x[r])) then
     29           if ((y[i]<=y[l]) and (y[i]>=y[r])) or ((y[i]>=y[l]) and (y[i]<=y[r])) then
     30             if (x[i]-x[l])*(y[i]-y[r])=(x[i]-x[r])*(y[i]-y[l]) then
     31             begin  //注意是线段上的点
     32               exit(false);
     33             end;
     34     exit(true);
     35   end;
     36 
     37 procedure add(x,y,f,w:longint);
     38   begin
     39     inc(len);
     40     edge[len].point:=y;
     41     edge[len].flow:=f;
     42     edge[len].cost:=w;
     43     edge[len].next:=p[x];
     44     p[x]:=len;
     45   end;
     46 
     47 function spfa:boolean;
     48   var i,j,f,r,x,y:longint;
     49   begin
     50     for i:=1 to t do
     51       d[i]:=-100000007;
     52     d[0]:=0;
     53     f:=1;
     54     r:=1;
     55     fillchar(v,sizeof(v),false);
     56     q[1]:=0;
     57     v[0]:=true;
     58     while f<=r do
     59     begin
     60       x:=q[f];
     61       v[x]:=false;
     62       i:=p[x];
     63       while i<>-1 do
     64       begin
     65         y:=edge[i].point;
     66         if edge[i].flow>0 then
     67           if d[x]+edge[i].cost>d[y] then
     68           begin
     69             pre[y]:=x;
     70             cur[y]:=i;
     71             d[y]:=d[x]+edge[i].cost;
     72             if not v[y] then
     73             begin
     74               inc(r);
     75               q[r]:=y;
     76               v[y]:=true;
     77             end;
     78           end;
     79         i:=edge[i].next;
     80       end;
     81       inc(f);
     82     end;
     83     if d[t]=-100000007 then exit(false) else exit(true);
     84   end;
     85 
     86 function maxcost:longint;
     87   var i,j:longint;
     88   begin
     89     maxcost:=0;
     90     while spfa do
     91     begin
     92       maxcost:=maxcost+d[t];
     93       i:=t;
     94       while i<>0 do
     95       begin
     96         j:=cur[i];
     97         dec(edge[j].flow);
     98         inc(edge[j xor 1].flow);
     99         i:=pre[i];
    100       end;
    101     end;
    102   end;
    103 
    104 begin
    105   len:=-1;
    106   fillchar(p,sizeof(p),255);
    107   readln(k);
    108   readln(n);
    109   for i:=1 to 2*n do
    110   begin
    111     readln(x[i],y[i],ch,na[i]);
    112     for j:=1 to length(na[i]) do
    113       na[i][j]:=upcase(na[i][j]);  //注意不区分大小写
    114   end;
    115   t:=2*n+1;
    116   for i:=1 to n do
    117   begin
    118     add(0,i,1,0);
    119     add(i,0,0,0);
    120     add(i+n,t,1,0);
    121     add(t,i+n,0,0);
    122   end;
    123 
    124   for i:=1 to n do
    125     for j:=n+1 to 2*n do
    126       a[i,j]:=1;   //注意
    127   ef:=true;
    128   while ef do
    129   begin
    130     s:='';
    131     read(ch);
    132     while ch<>' ' do
    133     begin
    134       s:=s+upcase(ch);
    135       if s='END' then ef:=false;  //大坑,有的人名字里会带end
    136       read(ch);
    137       if not ef and (ord(ch)>=65)  then
    138         ef:=true
    139       else if not ef then break;
    140     end;
    141     if not ef then break;
    142     i:=find(s);
    143     s:='';
    144     read(ch);
    145     while ch<>' ' do
    146     begin
    147       s:=s+upcase(ch);
    148       read(ch);
    149     end;
    150     j:=find(s);
    151     readln(a[i,j]);
    152     a[j,i]:=a[i,j];
    153   end;
    154   for i:=1 to n do
    155     for j:=n+1 to 2*n do
    156       if (sqr(x[i]-x[j])+sqr(y[i]-y[j])<=sqr(k)) and check(i,j) then
    157       begin
    158         add(i,j,1,a[i,j]);
    159         add(j,i,0,-a[i,j]);
    160       end;
    161   writeln(maxcost);
    162 end.
    View Code
  • 相关阅读:
    创建线程的几种方式(代码示例)
    关于多线程和异步
    c#面试题及答案
    《深入理解Android2》读书笔记(一)
    【转载】探探首页
    【转载】LruCache 源码解析
    【转载】LinearLayout 源码分析
    【转载】文件下载FileDownloader
    【转载】TabLayout 源码解析
    【转载】AsyncTask源码分析
  • 原文地址:https://www.cnblogs.com/phile/p/4473103.html
Copyright © 2011-2022 走看看