为啥改了下delta更新顺序能快这么多?!
  • 板块UVA1411 Ants
  • 楼主Wilson_Lee
  • 当前回复1
  • 已保存回复1
  • 发布时间2022/5/27 21:57
  • 上次更新2023/10/28 00:30:44
查看原帖
为啥改了下delta更新顺序能快这么多?!
513900
Wilson_Lee楼主2022/5/27 21:57

改前(TLE,3.00s):

#include<bits/stdc++.h>
using namespace std;

const int INF=1e10;
const int MAXN=105;
double w[MAXN][MAXN];
double la[MAXN],lb[MAXN]; 
double px[MAXN<<1],py[MAXN<<1];
bool va[MAXN],vb[MAXN];
int match[MAXN];
double upd[MAXN],delta;
int n;
bool dfs(int x)
{
	va[x]=1;
	for(int y=1;y<=n;++y)
	{
		if(!vb[y])
		{
			if(fabs(la[x]+lb[y]-w[x][y])<=1e-9)
			{
				vb[y]=1;
				if(!match[y] || dfs(match[y]))
				{
					match[y]=x;
					return 1;
				}
			}
			else
				upd[y]=min(upd[y],la[x]+lb[y]-w[x][y]);
		}
	}
	return 0;
}
void km()
{
	memset(la,-0x3f,sizeof(la));
	memset(lb,0,sizeof(lb));
	memset(match,0,sizeof(match));
	for(int i=1;i<=n;++i)
		for(int j=1;j<=n;++j)
			la[i]=max(la[i],w[i][j]);
	for(int i=1;i<=n;++i)
	{
		while(true)
		{
			memset(va,0,sizeof(va));
			memset(vb,0,sizeof(vb));
			if(dfs(i)) break;
			delta=INF;
			for(int j=1;j<=n;++j)
				if(!vb[j]) delta=min(delta,upd[i]);
			for(int j=1;j<=n;++j)
			{
				if(va[j]) la[j]-=delta;
				if(vb[j]) lb[j]+=delta;
			}
		}
	}
}
double cal(double x,double y,double xx,double yy)
{
	return sqrt((xx-x)*(xx-x)+(yy-y)*(yy-y));
}
int main()
{
	while(scanf("%d",&n)!=EOF)
	{
		for(int i=1;i<=n*2;++i)
			scanf("%lf %lf",&px[i],&py[i]);
		for(int i=1;i<=n;++i)
			for(int j=n+1;j<=n*2;++j)
				w[i][j-n]=-cal(px[i],py[i],px[j],py[j]);
		km();
		for(int i=1;i<=n;++i)
			printf("%d\n",match[i]);
	}
	return 0;
}

改后(AC,40ms):

#include<bits/stdc++.h>
using namespace std;

const double INF=1e10;
const int MAXN=105;
double w[MAXN][MAXN];
double la[MAXN],lb[MAXN]; 
int px[MAXN<<1],py[MAXN<<1];
bool va[MAXN],vb[MAXN];
int match[MAXN];
double delta;
int n;
bool dfs(int x)
{
	va[x]=1;
	for(int y=1;y<=n;++y)
	{
		if(!vb[y])
		{
			if(fabs(la[x]+lb[y]-w[x][y])<=1e-9)
			{
				vb[y]=1;
				if(!match[y] || dfs(match[y]))
				{
					match[y]=x;
					return 1;
				}
			}
		}
	}
	return 0;
}
void km()
{
	memset(la,-0x3f,sizeof(la));
	memset(lb,0,sizeof(lb));
	memset(match,0,sizeof(match));
	for(int i=1;i<=n;++i)
		for(int j=1;j<=n;++j)
			la[i]=max(la[i],w[i][j]);
	for(int i=1;i<=n;++i)
	{
		while(true)
		{
			memset(va,0,sizeof(va));
			memset(vb,0,sizeof(vb));
			if(dfs(i)) break;
			delta=INF;
			for(int j=1;j<=n;++j)
                if(va[j])
                    for(int k=1;k<=n;++k)
                        if(!vb[k])
                            delta=min(delta,la[j]+lb[k]-w[j][k]);
			for(int j=1;j<=n;++j)
			{
				if(va[j]) la[j]-=delta;
				if(vb[j]) lb[j]+=delta;
			}
		}
	}
}
double cal(int x,int y,int xx,int yy)
{
	return sqrt((xx-x)*(xx-x)+(yy-y)*(yy-y));
}
int main()
{
	while(scanf("%d",&n)!=EOF)
	{
		for(int i=1;i<=n*2;++i)
			scanf("%d %d",&px[i],&py[i]);
		for(int i=1;i<=n;++i)
			for(int j=n+1;j<=n*2;++j)
				w[j-n][i]=-cal(px[i],py[i],px[j],py[j]);
		km();
		for(int i=1;i<=n;++i)
			printf("%d\n",match[i]);
	}
	return 0;
}
2022/5/27 21:57
加载中...