poj 2112

  1 #include <cstdio>
  2 #include <cstring>
  3 const int MAXN=250;//点数的最大值
  4 const int MAXM=12500;//边数的最大值
  5 const int INF=0x3fffffff;
  6 
  7 struct Node
  8 {
  9     int from,to,next;
 10     int cap;
 11 }edge[MAXM];
 12 
 13 int tol;
 14 int head[MAXN];
 15 int dep[MAXN];
 16 int gap[MAXN];//gap[x]=y :说明残留网络中dep[i]==x的个数为y
 17 int matrix[250][250];
 18 int n;//n是总的点的个数,包括源点和汇点
 19 
 20 void init()
 21 {
 22     tol=0;
 23     memset(head,-1,sizeof(head));
 24 }
 25 
 26 void addedge(int u,int v,int w)
 27 {
 28     edge[tol].from=u;
 29     edge[tol].to=v;
 30     edge[tol].cap=w;
 31     edge[tol].next=head[u];
 32     head[u]=tol++;
 33     edge[tol].from=v;
 34     edge[tol].to=u;
 35     edge[tol].cap=0;
 36     edge[tol].next=head[v];
 37     head[v]=tol++;
 38 }
 39 void BFS(int start,int end)
 40 {
 41     memset(dep,-1,sizeof(dep));
 42     memset(gap,0,sizeof(gap));
 43     gap[0]=1;
 44     int que[MAXN];
 45     int front,rear;
 46     front=rear=0;
 47     dep[end]=0;
 48     que[rear++]=end;
 49     while(front!=rear)
 50     {
 51         int u=que[front++];
 52         if(front==MAXN)front=0;
 53         for(int i=head[u];i!=-1;i=edge[i].next)
 54         {
 55             int v=edge[i].to;
 56             if(dep[v]!=-1)continue;
 57             que[rear++]=v;
 58             if(rear==MAXN)rear=0;
 59             dep[v]=dep[u]+1;
 60             ++gap[dep[v]];
 61         }
 62     }
 63 }
 64 int SAP(int start,int end)
 65 {
 66     int res=0;
 67     BFS(start,end);
 68     int cur[MAXN];
 69     int S[MAXN];
 70     int top=0;
 71     memcpy(cur,head,sizeof(head));
 72     int u=start;
 73     int i;
 74     while(dep[start]<n)
 75     {
 76         if(u==end)
 77         {
 78             int temp=INF;
 79             int inser;
 80             for(i=0;i<top;i++)
 81                if(temp>edge[S[i]].cap)
 82                {
 83                    temp=edge[S[i]].cap;
 84                    inser=i;
 85                }
 86             for(i=0;i<top;i++)
 87             {
 88                 edge[S[i]].cap-=temp;
 89                 edge[S[i]^1].cap+=temp;
 90             }
 91             res+=temp;
 92             top=inser;
 93             u=edge[S[top]].from;
 94         }
 95         if(u!=end&&gap[dep[u]-1]==0)//出现断层,无增广路
 96           break;
 97         for(i=cur[u];i!=-1;i=edge[i].next)
 98            if(edge[i].cap!=0&&dep[u]==dep[edge[i].to]+1)
 99              break;
100         if(i!=-1)
101         {
102             cur[u]=i;
103             S[top++]=i;
104             u=edge[i].to;
105         }
106         else
107         {
108             int min=n;
109             for(i=head[u];i!=-1;i=edge[i].next)
110             {
111                 if(edge[i].cap==0)continue;
112                 if(min>dep[edge[i].to])
113                 {
114                     min=dep[edge[i].to];
115                     cur[u]=i;
116                 }
117             }
118             --gap[dep[u]];
119             dep[u]=min+1;
120             ++gap[dep[u]];
121             if(u!=start)u=edge[S[--top]].from;
122         }
123     }
124     return res;
125 }
126 void floyd(int matrix[250][250],int n)
127 {
128     for(int k = 1;k <= n;k++)
129     {
130         for(int i = 1;i <= n;i++)
131         {
132             for(int j = 1;j <= n;j++)
133             {
134                 if(matrix[i][j] > matrix[i][k] + matrix[k][j])
135                 {
136                     matrix[i][j] = matrix[i][k] + matrix[k][j];
137                 }
138             }
139         }
140     }
141 }
142 int main()
143 {
144     int k,c,m;
145     while(~scanf("%d%d%d",&k,&c,&m))
146     {
147         for(int i = 1;i <= k + c;i++)
148         {
149             for(int j = 1;j <= k + c;j++)
150             {
151                 scanf("%d",&matrix[i][j]);
152                 if(matrix[i][j] == 0 && i != j)
153                 {
154                     matrix[i][j] =INF;
155                 }
156             }
157         }
158         floyd(matrix,k + c);
159         int ans = 0;
160         for(int i = k + 1;i <= k + c;i++)
161         {
162             for(int j = 1;j <= k;j++)
163             {
164                 if(matrix[i][j] > ans)
165                 {
166                     ans = matrix[i][j];
167                 }
168             }
169         }
170         int s = 0,t = k + c + 1;
171         n = k + c + 2;
172         int right = ans,left = 0;
173         while(left + 1 < right)
174         {
175             int mid = (left + right) / 2;
176             init();
177             for(int i = k + 1;i <= k + c;i++)
178             {
179                 addedge(s,i,1);
180                 for(int j = 1;j <= k;j++)
181                 {
182                     if(matrix[i][j] <= mid)
183                     {
184                         addedge(i,j,1);
185                     }
186                 }
187             }
188             for(int j = 1;j <= k;j++)
189             {
190                 addedge(j,t,m);
191             }
192             if(SAP(s,t) == c)
193             {
194                 right = mid;
195             }
196             else
197             {
198                 left = mid;
199             }
200         }
201         printf("%d\n",right);
202     }
203     return 0;
204 }

 

题意:给出奶牛、机器之间的距离(包括奶牛-奶牛距离,机器-机器距离,奶牛-机器距离),以及机器的处理奶牛的最大数量,求走得最远的奶牛可以走的最近距离。

分析:源点构造边,指向每一个奶牛顶点,容量为1(因为每个顶点的奶牛数量都是1),然后二分法枚举最短的距离,奶牛-机器距离不大于限定的距离的建一条由奶牛指向机器的边,容量为1,每个机器都建一条指向汇点的边,容量为m.

 

posted @ 2013-08-01 23:26  Hogg  阅读(241)  评论(0编辑  收藏  举报