您的位置:首页 > 其它

Codefoces 277 E. Binary Tree on Plane

2017-04-10 19:14 211 查看
题目链接:http://codeforces.com/problemset/problem/277/E

参考了这篇题解:http://blog.csdn.net/Sakai_Masato/article/details/50775315

没看出来是费用流啊...我好菜啊。

我写得有一点和上面这篇题解不同:在判断是否无解时我直接记录最大流,判断最大流是否等于$n-1$(似乎是等价的...)

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<cstdlib>
#include<cmath>
#include<cstring>
using namespace std;
#define maxn 1010
#define inf 0x7fffffff
#define llg int
#define sqr(_) ((_)*(_))
#define yyj(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
llg n,m;

struct node
{
llg u,v,c,next;
double w;
};

struct FLOW
{
llg cnt,maxflow,S,T,pre[maxn],N;
llg head[maxn],dl[maxn*maxn];
bool bj[maxn];
double mincost,dis[maxn];
node e[maxn*maxn];

void init()
{
memset(head,-1,sizeof(head));
mincost=cnt=maxflow=0;
maxflow=0; mincost=0;
}

void link(llg u,llg v,double w,llg c)
{
e[cnt].u=u,e[cnt].v=v,e[cnt].w=w,e[cnt].c=c;
e[cnt].next=head[u],head[u]=cnt++;

e[cnt].u=v,e[cnt].v=u,e[cnt].w=-w,e[cnt].c=0;
e[cnt].next=head[v],head[v]=cnt++;
}

void updata()
{
llg f=inf;
for (llg i=T;i!=S;i=e[pre[i]].u) f=min(f,e[pre[i]].c);
maxflow+=f;
for (llg i=T;i!=S;i=e[pre[i]].u)
{
e[pre[i]].c-=f;
e[pre[i]^1].c+=f;
mincost+=(double)f*e[pre[i]].w;
}
}

bool spfa()
{
llg u,v;
double w;
memset(pre,-1,sizeof(pre));
memset(bj,0,sizeof(bj));
for (llg i=0;i<=N;i++) dis[i]=inf;
llg l=0,r=1;
dl[r]=S; bj[S]=1; dis[S]=0;
do
{
bj[u=dl[++l]]=0;
for (llg i=head[u];i!=-1;i=e[i].next)
{
v=e[i].v,w=e[i].w;
if (e[i].c && dis[v]>dis[u]+w)
{
dis[v]=dis[u]+w;
pre[v]=i;
if (!bj[v]) bj[v]=1,dl[++r]=v;
}
}
}while (l<r);

if (pre[T]==-1) return 0;
return 1;
}

void work()
{
while (spfa())
updata();
}

}G;

inline int getint()
{
int w=0,q=0; char c=getchar();
while((c<'0' || c>'9') && c!='-') c=getchar(); if(c=='-') q=1,c=getchar();
while (c>='0' && c<='9') w=w*10+c-'0', c=getchar(); return q ? -w : w;
}

struct POINT{double x,y;}po[maxn];

bool cmp(const POINT&x,const POINT&y) {return x.y==y.y?x.x<y.x:x.y<y.y;}

double dis(const POINT&x,const POINT&y) {return sqrt(sqr(x.x-y.x)+sqr(x.y-y.y));}

int main()
{
yyj("flow");
cin>>n;
G.init();
G.N=n*2+10;
for (llg i=1;i<=n;i++) scanf("%lf%lf",&po[i].x,&po[i].y);
sort(po+1,po+n+1,cmp);
reverse(po+1,po+1+n);
for (llg i=1;i<=n;i++)
for (llg j=i+1;j<=n;j++)
if (po[i].y>po[j].y)
G.link(i,j+n,dis(po[i],po[j]),(llg)1);
G.S=2*n+1,G.T=2*n+2;
for (llg i=1;i<=n;i++)
{
G.link(G.S,i,0,(llg)2);
G.link(i+n,G.T,0,(llg)1);
}
G.work();
if (G.maxflow!=n-1) {cout<<-1;} else printf("%.9lf",G.mincost);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: