经典的图论建模题;

先拿开的等级问题不看;

每个物品本身的价格就是有一个自定义源点到这个点距离;

有了A物品B物品优惠为W就代表由B到A的有向路权值为W;

最后的最小花费就是源点的点1的最短路径(酋长编号总是1);

然后我们再考虑等级问题。穷举每个点作为最高等级,相应的就可以确定哪些点不能访问,然后求最短路;

最终找一个以点i等级为最高等级的情况使源点到1的最短路径最小即可,易知时间复杂度为O(n^3);

  1 var tree:array[0..80000] of integer;
  2     x,y:array[0..10010] of longint;
  3     a:array[0..20010] of longint;         //表示离散化乎的标号对应的区间
  4     f:array[0..10000000] of boolean;
  5     ff:array[0..10010] of boolean;
  6     i,j,k,n,t,s:longint;
  7 procedure sort(l,r: longint);
  8   var i,j,x,y: longint;
  9   begin
 10     i:=l;
 11     j:=r;
 12     x:=a[(l+r) div 2];
 13     repeat
 14       while a[i]<x do inc(i);
 15       while x<a[j] do dec(j);
 16       if not(i>j) then
 17       begin
 18         y:=a[i];
 19         a[i]:=a[j];
 20         a[j]:=y;
 21         inc(i);
 22         j:=j-1;
 23       end;
 24     until i>j;
 25     if l<j then sort(l,j);
 26     if i<r then sort(i,r);
 27   end;
 28 procedure putdown(i,p,q:longint);         //传递标记
 29   begin
 30     if p<>q then
 31     begin
 32       tree[i*2]:=tree[i];
 33       tree[i*2+1]:=tree[i];
 34       tree[i]:=0;
 35     end;
 36   end;
 37 procedure build(i,p,q,l,r,x:longint);
 38   var m:longint;
 39   begin
 40     if (a[p]>=l) and (r>=a[q]) then tree[i]:=x
 41     else begin
 42       if tree[i]<>0 then putdown(i,p,q);
 43       m:=(p+q) div 2;
 44       if l<=a[m] then
 45       begin
 46         build(i*2,p,m,l,r,x);
 47       end;
 48       if r>a[m] then
 49       begin
 50         build(i*2+1,m+1,q,l,r,x);
 51       end;
 52     end;
 53   end;
 54 procedure dfs(i,p,q:longint);              //统计多少可见海报
 55   var m:longint;
 56   begin
 57     if (tree[i]>0) and not ff[tree[i]] then
 58     begin
 59       s:=s+1;
 60       ff[tree[i]]:=true;
 61     end
 62     else if (tree[i]=0) and (p<>q) then
 63     begin
 64       m:=(p+q) div 2;
 65       dfs(i*2,p,m);
 66       dfs(i*2+1,m+1,q);
 67     end;
 68   end;
 69 begin
 70   readln(t);
 71   for i:=1 to t do
 72   begin
 73     k:=0;
 74     fillchar(f,sizeof(f),false);
 75     readln(n);                        
 76     for j:=1 to n do 
 77     begin
 78       readln(x[j],y[j]);
 79       if not f[x[j]] then                        //离散化
 80       begin
 81         k:=k+1;
 82         a[k]:=x[j];
 83         f[x[j]]:=true;
 84       end;
 85       if not f[y[j]] then
 86       begin
 87         k:=k+1;
 88         a[k]:=y[j];
 89         f[y[j]]:=true;
 90       end;
 91     end;
 92     sort(1,k);
 93     fillchar(tree,sizeof(tree),0);
 94     for j:=1 to n do                     
 95       build(1,1,k,x[j],y[j],j);
 96     s:=0;
 97     fillchar(ff,sizeof(ff),false);
 98     dfs(1,1,k);
 99     writeln(s);
100   end;
101 end.
View Code

PS:千万不要以为酋长等级最高……

 

posted on 2013-11-30 15:33  acphile  阅读(130)  评论(0编辑  收藏  举报