bzoj4443

来源:互联网 发布:淘宝购物车刷新 编辑:程序博客网 时间:2024/06/11 21:54

先开始想的是一个完美匹配,后面不断优化到了直接一个最大匹配就好了。。。囧。。。。

#include<iostream>#include<cstdio>#include<algorithm>using namespace std;struct edgee{int from, to,value;edgee(int from, int to, int v) :from(from), to(to), value(v){}edgee(){}};edgee edge[200000];int first[600], nextt[200000],edgetot;int n, m, k;int map[300][300];int visit[800], value[800], slack[800];int match[800];void addedge(int from, int to,int value){edge[edgetot] = edgee(from, to,value);nextt[edgetot] = first[from];first[from] = edgetot++;edge[edgetot] = edgee(to, from,value);nextt[edgetot] = first[to];first[to] = edgetot++;}void addedge(int k){edgetot = 0;for (int i = 0; i <= n+m + 1; i++)first[i] = -1;for (int i = n + 1; i <= m + n; i++)value[i] = 0;for (int i = 1; i <= n; i++){value[i] = -1000000000;for (int j = 1; j <= m; j++){if (map[i][j] <= k)value[i] = max(value[i], 1), addedge(i, j + n,1);//else//value[i] = max(value[i], -1),addedge(i,j+n,-1);}}}bool dfs(int num){visit[num] = 1;for (int i = first[num]; i != -1; i = nextt[i]){int to = edge[i].to;if (visit[to])continue;int t = value[num] + value[to]-edge[i].value;if (t == 0){visit[to] = 1;if (match[to] == 0 || dfs(match[to])){match[to] = num;return true;}}elseslack[to] = min(slack[to], t);}return false;}int control(int k){addedge(k);for (int j = 1; j <= n+m + 1; j++) match[j] = 0;for (int i = 1; i <= n; i++){for (int j = 1; j <= n+m + 1; j++)visit[j] = 0,slack[j]=1000000000;while (!dfs(i)){break;int t = 1000000000;for (int k = n+1; k <= n+m; k++)if (!visit[i])t = min(t, slack[k]);for (int i = 1; i <= n; i++)if (visit[i])value[i] -= t,visit[i]=0;for (int i = n + 1; i <= n + m; i++)if (visit[i])value[i] += t, visit[i] = 0;}}int ans = 0;for (int i = 1 + n; i <= m + n; i++)if (match[i])ans = ans + ((value[i] + value[match[i]]>0 )? value[i] + value[match[i]]:0);return ans;}int main(){scanf("%d%d%d", &n, &m, &k);int l = 1000000010; int r = -1;for (int i = 1; i <= n; i++){for (int j = 1; j <= m; j++)scanf("%d", &map[i][j]),l=min(l,map[i][j]),r=max(r,map[i][j]);}k = n - k + 1;while (l < r){int mid = (l + r) >> 1;if (control(mid) >= k)r = mid;elsel = mid + 1;}printf("%d\n", r);}

原创粉丝点击