2012-A3-0026
从 Trac 迁移的文章
这是从旧校内 Wiki 迁移的文章,可能存在一些样式问题,您可以向 memset0 反馈。
原文章内容如下:
{{{
#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
#include<numeric>
#include<cmath>
#include<algorithm>
#include<set>
#include<functional>
using namespace std;
//using namespace rel_ops;
typedef unsigned u32;
const double eps = 1e-8;
struct real{
double z;
real(){};real(double x):z(x){}
};
real operator *(const real& a,const real& b){
return real(a.z*b.z);
}
real operator /(const real& a,const real& b){
return real(a.z/b.z);
}
bool operator == (const real&a ,const real& b){
return fabs(a.z/b.z-1.0)<eps;
}
bool operator < (const real &a,const real &b){
return a.z/b.z+eps<1.0;
}
typedef pair<real,u32> eT;
eT operator +(const eT& a,const eT& b){
return eT(a.first*b.first,a.second+b.second);
}
eT operator -(const eT&a,const eT& b){
return eT(a.first/b.first,a.second-b.second);
}
u32 pts[5120];
real pos[10][5120];
u32 cmpk;
struct cmp{
bool operator()(u32 a,u32 b){
return pos[cmpk][b]<pos[cmpk][a]||pos[cmpk][a]==pos[cmpk][b]&&pts[a]>pts[b];
}
};
const u32 N =100;
eT e[10][N];
u32 m1[10],m2[N];
eT KuhnMunkras(u32 m,u32 n, eT e[][N], u32 * m1, u32 * m2) {
static u32 s[N + 1], t[N],p, q, i, j, k;
static eT l1[N],l2[N];
for(i = 0; i < m; i++)
for (l1[i] = eT(real(0),0) ,j = 0; j < n; j++)
if(l1[i]<e[i][j])l1[i]=e[i][j];
for(i=0;i<n;l2[i++] = eT(real(1.0),0u));
memset(m1,0xff,m*sizeof(u32));
memset(m2,0xff,n*sizeof(u32));
for (i =0;i<m;i++) {
memset(t,0xff,n*sizeof(u32));
for (s[p=q=0]=i;p<=q&&!~m1[i];p++)
for (k=s[p],j=0;j<n&&!~m1[i];j++)
if (l1[k]+l2[j]==e[k][j]&&!~t[j]) {
s[++q]=m2[j];t[j] = k;
if (!~s[q])
for(p=j;~p;j=p){
m2[j]=k=t[j];
p= m1[k];
m1[k] = j;
}
}
if (!~m1[i]) {
eT p(real(1e10),0);--i;
for (k = 0; k<= q;k++)
for (j = 0;j< n; j++)
if (!~t[j] && l1[s[k]] + l2[j] < p+ e[s[k]][j])
p = l1[s[k]] + l2[j] - e[s[k]][j];
for (j = 0; j < n; j++)
if(~t[j])l2[j] = l2[j]+p;
for (k = 0; k <= q; k++)l1[s[k]] = l1[s[k]]- p;
}
}
eT ret(real(1.0),0u);
for (i = 0; i < m; i++)
ret = ret + e[i][m1[i]];
return ret;
}
priority_queue<u32,vector<u32> , cmp > useful[10];
int main(){
for(u32 m,n;scanf("%u%u",&n,&m)==2;){
for(u32 i=0;i<m;++i)scanf("%u",pts+i);
for(u32 i=0;i<n;++i){
cmpk=i;
for(u32 j=0;j<m;++j){
scanf("%lf",&pos[i][j].z);
useful[i].push(j);
if(useful[i].size()>n)useful[i].pop();
}
}
for(u32 i=0,j;i<n;++i){
for(j=0;j<m&&pos[i][j]<eps;++j);
if(j==m){
sort(pts,pts+m,greater<u32>());
printf("%u\n",accumulate(pts,pts+n,0u));
n = 0; break;
}
}
if(!n)continue;
set<u32> temp;
for(u32 i=0;i<n;++i)
for(;useful[i].size();useful[i].pop())
temp.insert(useful[i].top());
m =0;
for(__typeof(temp.end()) it =temp.begin();
it!=temp.end();++it,++m){
pts[m] = pts[*it];
for(u32 j=0;j<n;++j)
e[j][m] = eT(real(pos[j][m]=pos[j][*it]),pts[m]);
}
printf("%u\n",KuhnMunkras(n,m,e,m1,m2).second);
}
return 0;
}
}}}
#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
#include<numeric>
#include<cmath>
#include<algorithm>
#include<set>
#include<functional>
using namespace std;
//using namespace rel_ops;
typedef unsigned u32;
const double eps = 1e-8;
struct real{
double z;
real(){};real(double x):z(x){}
};
real operator *(const real& a,const real& b){
return real(a.z*b.z);
}
real operator /(const real& a,const real& b){
return real(a.z/b.z);
}
bool operator == (const real&a ,const real& b){
return fabs(a.z/b.z-1.0)<eps;
}
bool operator < (const real &a,const real &b){
return a.z/b.z+eps<1.0;
}
typedef pair<real,u32> eT;
eT operator +(const eT& a,const eT& b){
return eT(a.first*b.first,a.second+b.second);
}
eT operator -(const eT&a,const eT& b){
return eT(a.first/b.first,a.second-b.second);
}
u32 pts[5120];
real pos[10][5120];
u32 cmpk;
struct cmp{
bool operator()(u32 a,u32 b){
return pos[cmpk][b]<pos[cmpk][a]||pos[cmpk][a]==pos[cmpk][b]&&pts[a]>pts[b];
}
};
const u32 N =100;
eT e[10][N];
u32 m1[10],m2[N];
eT KuhnMunkras(u32 m,u32 n, eT e[][N], u32 * m1, u32 * m2) {
static u32 s[N + 1], t[N],p, q, i, j, k;
static eT l1[N],l2[N];
for(i = 0; i < m; i++)
for (l1[i] = eT(real(0),0) ,j = 0; j < n; j++)
if(l1[i]<e[i][j])l1[i]=e[i][j];
for(i=0;i<n;l2[i++] = eT(real(1.0),0u));
memset(m1,0xff,m*sizeof(u32));
memset(m2,0xff,n*sizeof(u32));
for (i =0;i<m;i++) {
memset(t,0xff,n*sizeof(u32));
for (s[p=q=0]=i;p<=q&&!~m1[i];p++)
for (k=s[p],j=0;j<n&&!~m1[i];j++)
if (l1[k]+l2[j]==e[k][j]&&!~t[j]) {
s[++q]=m2[j];t[j] = k;
if (!~s[q])
for(p=j;~p;j=p){
m2[j]=k=t[j];
p= m1[k];
m1[k] = j;
}
}
if (!~m1[i]) {
eT p(real(1e10),0);--i;
for (k = 0; k<= q;k++)
for (j = 0;j< n; j++)
if (!~t[j] && l1[s[k]] + l2[j] < p+ e[s[k]][j])
p = l1[s[k]] + l2[j] - e[s[k]][j];
for (j = 0; j < n; j++)
if(~t[j])l2[j] = l2[j]+p;
for (k = 0; k <= q; k++)l1[s[k]] = l1[s[k]]- p;
}
}
eT ret(real(1.0),0u);
for (i = 0; i < m; i++)
ret = ret + e[i][m1[i]];
return ret;
}
priority_queue<u32,vector<u32> , cmp > useful[10];
int main(){
for(u32 m,n;scanf("%u%u",&n,&m)==2;){
for(u32 i=0;i<m;++i)scanf("%u",pts+i);
for(u32 i=0;i<n;++i){
cmpk=i;
for(u32 j=0;j<m;++j){
scanf("%lf",&pos[i][j].z);
useful[i].push(j);
if(useful[i].size()>n)useful[i].pop();
}
}
for(u32 i=0,j;i<n;++i){
for(j=0;j<m&&pos[i][j]<eps;++j);
if(j==m){
sort(pts,pts+m,greater<u32>());
printf("%u\n",accumulate(pts,pts+n,0u));
n = 0; break;
}
}
if(!n)continue;
set<u32> temp;
for(u32 i=0;i<n;++i)
for(;useful[i].size();useful[i].pop())
temp.insert(useful[i].top());
m =0;
for(__typeof(temp.end()) it =temp.begin();
it!=temp.end();++it,++m){
pts[m] = pts[*it];
for(u32 j=0;j<n;++j)
e[j][m] = eT(real(pos[j][m]=pos[j][*it]),pts[m]);
}
printf("%u\n",KuhnMunkras(n,m,e,m1,m2).second);
}
return 0;
}