[CF277E]Binary Tree on Plane
题意
给你平面上
其中,点
如果不存在满足条件的二叉树,输出
思路
题目给出了对每个点的度数的限制,并且父亲和孩子不能随便取,考虑费用流。
把每个点拆成两个点
代码
#include<bits/stdc++.h>
#define MAXN 410
#define INF 2000000000
using namespace std;
int n,s,t;
struct point
{
int x,y;
}po[MAXN];
bool cmp(point a,point b)
{
return a.y<b.y;
}
struct edge
{
int to,from,nxt,w;
double c;
}ed[MAXN*MAXN];
int head[MAXN],tot=1;
void add(int u,int v,int w,double c)
{
ed[++tot].to=v;
ed[tot].w=w;
ed[tot].c=c;
ed[tot].from=u;
ed[tot].nxt=head[u];
head[u]=tot;
}
int pre[MAXN],vis[MAXN],flo[MAXN];
int arr[MAXN],up=0,down=0,now;
int flow;
double cost;
double dis[MAXN];
bool spfa()
{
up=down=0;
arr[++down]=s;
for(int i=0;i<=n*2+1;i++)
dis[i]=INF;
dis[s]=0;
vis[s]=1;
flo[s]=INF;
while(up<down)
{
now=arr[++up];
vis[now]=0;
for(int i=head[now];i;i=ed[i].nxt)
{
int v=ed[i].to;
double c=ed[i].c;
if(!ed[i].w)continue;
if(dis[v]>dis[now]+c)
{
dis[v]=dis[now]+c;
flo[v]=min(flo[now],ed[i].w);
pre[v]=i;
if(!vis[v])
{
vis[v]=1;
arr[++down]=v;
}
}
}
}
if(dis[t]<INF)return true;
else return false;
}
void costflow()
{
flow=cost=0;
int now,last;
while(spfa())
{
flow+=flo[t];
cost+=dis[t];
now=t;
while(now!=s)
{
last=pre[now];
ed[last].w-=flo[t];
ed[last^1].w+=flo[t];
now=ed[last].from;
}
}
}
double getdis(point a,point b)
{
return sqrt((a.x-b.x+0.0)*(a.x-b.x+0.0)+(a.y-b.y+0.0)*(a.y-b.y+0.0));
}
int main()
{
scanf("%d",&n);
s=0;
t=2*n+1;
for(int i=1;i<=n;i++)
scanf("%d%d",&po[i].x,&po[i].y);
sort(po+1,po+n+1,cmp);
for(int i=1;i<=n;i++)
{
add(s,i,2,0);
add(i,s,0,0);
add(i+n,t,1,0);
add(t,i+n,0,0);
for(int j=1;j<i;j++)
{
if(po[j].y<po[i].y)
{
add(i,j+n,1,getdis(po[i],po[j]));
add(j+n,i,1,-getdis(po[i],po[j]));
}
}
}
costflow();
if(flow==n-1)printf("%lf",cost);
else printf("-1");
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】