hdu 2853
Posted gggyt
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu 2853相关的知识,希望对你有一定的参考价值。
题意:
有n个军队,m个任务;
下面给出n*m的矩阵,表示每个军队做每个任务的效率;
最后一行给出n个军队的原匹配任务;
问最少改变多少个匹配关系使得效率最大,且输出最大效率值;
这道题我当时看着真的没什么思路,然后查了波题解,觉得真的是个好题啊。
他要的是在现有的匹配上改变次数少并且优的,那么我们怎么处理?
意思就是原来给出的在某种程度上比其他的要更优, 那么我们同时扩大K倍,原来匹配的扩大K倍+1。
那么再次匹配就得到想要的答案了!
/* gyt Live up to every day */ #include<cstdio> #include<cmath> #include<iostream> #include<algorithm> #include<vector> #include<stack> #include<cstring> #include<queue> #include<set> #include<string> #include<map> #include <time.h> #define PI acos(-1) using namespace std; typedef long long ll; typedef double db; const int maxn = 3000+10; const int maxm=5000+10; const int modd = 10000007; const int INF = 0x3f3f3f; const db eps = 1e-9; int lx[maxn], ly[maxn], vx[maxn], vy[maxn]; int slack[maxn], match[maxn]; int a[maxn][maxn]; int n, m, nx, ny; int dfs(int u) { vx[u]=1; for (int i=1; i<=ny; i++) { if (vy[i]) continue; int t=lx[u]+ly[i]-a[u][i]; if (t==0) { vy[i]=1; if (match[i]==-1||dfs(match[i])) { match[i]=u; return 1; } } else if(slack[i]>t) { slack[i]=t; } } return 0; } int KM() { memset(ly, 0, sizeof(ly)); memset(match, -1, sizeof(match)); memset(lx, -INF, sizeof(lx)); for (int i=1; i<=nx; i++) { for (int j=1; j<=ny; j++) { lx[i]=max(lx[i], a[i][j]); } } for (int i=1; i<=nx; i++) { memset(slack, INF, sizeof(slack)); while(1) { memset(vx, 0, sizeof(vx)); memset(vy, 0, sizeof(vy)); if (dfs(i)) break; int d=INF; for (int j=1; j<=ny; j++) { if (!vy[j]&&slack[j]<d) { d=slack[j]; } } for (int j=1; j<=nx; j++) { if (vx[j]) lx[j]-=d; } for (int j=1; j<=ny; j++) { if (vy[j]) ly[j]+=d; else slack[j]-=d; } } } int ans=0; for (int i=1; i<=ny; i++) { if (match[i]>-1&&a[match[i]][i]) { ans+=a[match[i]][i]; } } return ans; } void solve() { while(scanf("%d%d", &n, &m)!=EOF) { nx=n, ny=m; for (int i=1; i<=n; i++) { for (int j=1; j<=m; j++) { scanf("%d", &a[i][j]); a[i][j]*=100; } } int sum=0; for (int i=1; i<=n; i++) { int t; scanf("%d", &t); sum+=a[i][t]; a[i][t]++; } int hh=KM(); int ans=hh/100-sum/100; printf("%d %d\n", n-hh%100, ans); } } int main() { int t = 1; //freopen("in.txt", "r", stdin); //scanf("%d", &t); while(t--) solve(); return 0; }
以上是关于hdu 2853的主要内容,如果未能解决你的问题,请参考以下文章
洛谷P2853 [USACO06DEC]Cow Picnic S 题解