【 확장 km 】 hdu 4744
우 리 는 km 가 가장 좋 은 매 칭 을 할 때 매번 같은 서브 맵 에서 가장 큰 매 칭 을 하 는 것 을 알 고 있 습 니 다. 만약 에 같은 서브 맵 을 찾 지 못 하면 정상 표 지 를 수정 하여 같은 서브 맵 을 확대 하 는 것 을 알 수 있 습 니 다. 그러면 이 문 제 는 사실은 여러 번 확대 되 는 km 임 을 알 수 있 습 니 다. 즉, 같은 서브 맵 을 찾 을 때마다 유량 을 한 번 확대 하 는 동시에 한 변 으로 여러 번 선택 할 수 있 기 때 문 입 니 다.그러면 똑 같은 서브 맵 도 여러 개 있 기 때문에 알고리즘 을 수정 하고 나 왔 습 니 다. 똑 같은 서브 맵 을 찾 을 때마다 하 나 를 찾 으 면 넓 어 지고 넓 어 질 수 있 는 똑 같은 서브 맵 을 찾 지 못 할 때 정상 표 지 를 수정 합 니 다.
93ms 를 뛰 었 으 니 지금 이 가장 빠 를 것 입 니 다. G + + 로 교차 하 는 것 이 느 릴 것 입 니 다. 그래서 사실은 유 대사 보다 느 립 니 다.
#include <cstdio>
#include <cstdlib>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <cmath>
#define sqr(x) ((x)*(x))
const int oo=1073741819;
using namespace std;
int n;
int vx[200],vy[200],lx[200],ly[200],slack[200],f[200],g[200];
int x[200],y[200],z[200],a[200],b[200],c[200][200],w[200][200];
double dist(int i,int j)
{
return sqrt((double)(sqr(x[i]-x[j])+sqr(y[i]-y[j])+sqr(z[i]-z[j])));
}
bool km(int x)
{
if (vx[x]) return 0;
vx[x]=1;
for (int i=1;i<=n;i++) {
if (vy[i]) continue;
int tmp=lx[x]+ly[i]-w[x][i];
if (!tmp) {
vy[i]=1;
if (b[i]) {
f[x]=i,g[x]=0;
return 1;
}
for (int j=1;j<=n;j++)
if (c[j][i] && km(j)) {
f[x]=i,g[x]=j;
return 1;
}
}
else slack[i]=min(slack[i],tmp);
}
return 0;
}
int push(int x)
{
int d=a[x];
for (int i=x;i;i=g[i]) {
if (g[i]) d=min(d,c[g[i]][f[i]]);
else d=min(d,b[f[i]]);
}
int sum=0;
a[x]-=d;
for (int i=x;i;i=g[i]) {
if (g[i]) sum-=d*w[g[i]][f[i]],c[g[i]][f[i]]-=d;
else b[f[i]]-=d;
sum+=d*w[i][f[i]],c[i][f[i]]+=d;
}
return sum;
}
int main()
{
freopen("hdu4744.in","r",stdin);
freopen("hdu4744.out","w",stdout);
for (;;) {
scanf("%d",&n);
if (!n) break;
for (int i=1;i<=n;i++) {
scanf("%d%d%d%d",&x[i],&y[i],&z[i],&a[i]);
b[i]=a[i];
lx[i]=0,ly[i]=0;
}
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++) {
if (i!=j) w[i][j]=-floor(dist(i,j));
else w[i][j]=-oo;
c[i][j]=0;
lx[i]=max(lx[i],w[i][j]);
}
int ans=0;
for (int i=1;i<=n;i++) {
for (;a[i];) {
for (int j=1;j<=n;j++) slack[j]=oo;
for (;a[i];) {
for (int j=1;j<=n;j++) vx[j]=vy[j]=0;
if (km(i))
ans+=push(i);
else break;
}
if (!a[i]) break;
int d=oo;
for (int i=1;i<=n;i++)
if (!vy[i]) d=min(d,slack[i]);
for (int i=1;i<=n;i++) {
if (vx[i]) lx[i]-=d;
if (vy[i]) ly[i]+=d;
}
}
}
for (int i=1;i<=n;i++)
if (c[i][i]) ans=1;
printf("%d
",-ans);
}
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.