bzoj 1433: [ZJOI2009]假期的宿舍 最大流

貌似弃坑了的样子...QAQ...其实并没有啊...

一到暑假就颓废了QAQ...懒得写博客...所以还是来补一补吧...

点我看题

题目就不贴了,直接bzoj看吧...

题目大意:  一个学校里有n个人, 有 几个是学生,剩下的是拜访的,这些学生中,有几个要回家,有几个不回家要在学校过夜,然后拜访的也要在学校过夜。可是每一个人只睡他认识的人......的床。问是否有一个方案使得这些不回家的学生和拜访都能睡到床。

思路:难得的最大流裸题吧...毕竟很少有自己能一眼的了...很显然可以这样做:

对于每一个人,建一个点x,同时建多一个点xx,表示他们对应的床。当然拜访学生是没有床的,但是我为了方便建了。

 源点和每一个人的点x连一条边,如果这个人是不回家的学生或者是拜访的人,辣么流量为 1 表示这是需要床的人 否则为 0 表示这是不需要床的人...这个流量为0的边要建,不然貌似会在分层的时候炸...QAQ...

然后汇点和每一个人的点xx连一条边,如果这个人是学生,辣么流量为 1 表示有床,否则为0 表示没有床,一样,流量为0的边要建。

然后如果 人 i  认识 人 j ...辣么 人 i 的就可以睡人 j .......的床(不要问我为什么要把人和床分开一点...手动滑稽)。所以就 人 i 的 点x 和人 j 的点xx 连一条边 流量 1

 因为这个所以 每个人的点 x 要和 xx 连一条流量1的边

某些坑点?(也许并不是,只是我傻了没看到,所以wa了一次)

提一下吧:

这个随机的数有可能是1或0所以还是不要偷懒乖乖特判是否学生

然后就给代码吧:

  1 type
  2   node=record
  3       x,y:longint;
  4       flow:longint;
  5       next:longint;
  6   end;
  7 var first,dis,a:array[0..150]of longint;
  8     q:array[0..100000]of longint;
  9     n,tot,p,t:longint;
 10     i,j:longint;
 11     e:array[0..100000]of node;
 12     ans,sum:longint;
 13     x,y,z:longint;
 14 function bfs(s,t:longint):boolean;
 15 var head,tail:longint;
 16     i,now,y:longint;
 17 begin
 18   head:=1;
 19   tail:=1;
 20   for i:=0 to p do
 21   dis[i]:=-1;
 22   q[1]:=s;
 23   dis[s]:=0;
 24   while head<=tail do
 25   begin
 26     now:=q[head];
 27     i:=first[now];
 28     while i<>-1 do
 29     begin
 30       y:=e[i].y;
 31       if (dis[y]<0)and(e[i].flow>0) then
 32       begin
 33         dis[y]:=dis[now]+1;
 34         inc(tail);
 35         q[tail]:=y;
 36       end;
 37       i:=e[i].next;
 38     end;
 39     inc(head);
 40   end;
 41   if dis[t]=-1 then exit(false) else exit(true);
 42 end;
 43 procedure adde(x,y,f:longint);
 44 begin
 45   e[tot].next:=first[x];
 46   e[tot].x:=x;
 47   e[tot].y:=y;
 48   e[tot].flow:=f;
 49   first[x]:=tot;
 50   inc(tot);
 51 end;
 52 function dfs(x,mx:longint):longint;
 53 var i,k:longint;
 54 begin
 55   if x=p then exit(mx);
 56   i:=first[x];
 57   while i<>-1 do
 58   begin
 59     y:=e[i].y;
 60     if (e[i].flow>0)and(dis[y]=dis[x]+1) then
 61     begin
 62       if e[i].flow>mx then k:=dfs(y,mx) else k:=dfs(y,e[i].flow);
 63       dec(e[i].flow,k);
 64       inc(e[i xor 1].flow,k);
 65       if k>0 then exit(k);
 66     end;
 67     i:=e[i].next;
 68   end;
 69   exit(0);
 70 end;
 71 begin
 72   read(t);
 73   while t>0 do
 74   begin
 75     fillchar(e,sizeof(e),0);
 76     dec(t);
 77     read(n);
 78     p:=2*n+1;
 79     ans:=0;
 80     sum:=0;
 81     tot:=0;
 82     for i:=0 to p do
 83     first[i]:=-1;
 84     for i:=1 to n do
 85     begin
 86       read(a[i]);
 87       if a[i]=1 then
 88       begin
 89         adde(i+n,p,1);
 90         adde(p,i+n,0);
 91       end else
 92       begin
 93         adde(i+n,p,0);
 94         adde(p,i+n,0);
 95         inc(sum);
 96       end;
 97     end;
 98     for i:=1 to n do
 99     begin
100       read(x);
101       if a[i]=0 then
102       begin
103         adde(0,i,1);
104         adde(i,0,0);
105       end else
106       begin
107         if x=0 then
108         begin
109           adde(0,i,1);
110           adde(i,0,0);
111           inc(sum);
112         end else
113         begin
114           adde(0,i,0);
115           adde(i,0,0);
116         end;
117       end;
118     end;
119     for i:=1 to n do
120       for j:=1 to n do
121       begin
122         read(x);
123         if (x=1)or(i=j) then
124         begin
125           adde(i,n+j,1);
126           adde(n+j,i,0);
127         end;
128       end;
129     while bfs(0,p) do
130     begin
131       repeat
132         z:=dfs(0,1 << 25);
133         inc(ans,z);
134       until z>0;
135     end;
136     if ans>=sum then writeln('^_^') else writeln('T_T');
137   end;
138 end.
View Code

pascal代码应该很好看的吧...要c++的没有...>_<

 

posted @ 2017-07-18 16:39  Bunnycxk  阅读(228)  评论(0编辑  收藏  举报