#include<map>
#include<set>
#include<stack>
#include<queue>
#include<cmath>
#include<cstring>
#include<climits>
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
#define LL long long
inline int read() {
bool f=0;int x=0;char c=getchar();
while(c<'0'||'9'<c){if(c==EOF)exit(0);if(c=='-')f=1;c=getchar();}
while('0'<=c&&c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar();
return !f?x:-x;
}
#define MAXN 100000
#define eps (1e-6)
#define MAXM 120000
#define INF 0x3f3f3f3f
struct Edge{
int nxt,v,cap;double w;
}edge[2*MAXM+5];
int ecnt,head[MAXN+5],cur[MAXN+5];
void Init(){
ecnt=-1,memset(head,-1,sizeof(head));
return ;
}
void Addedge(int u,int v,int cap,double w){
//printf("%d %d %d %f\n",u,v,cap,w);
edge[++ecnt]=(Edge){head[u],v,cap,w},head[u]=ecnt;
edge[++ecnt]=(Edge){head[v],u,0,-w},head[v]=ecnt;
return ;
}
int N,S,T;
double cost;
double dep[MAXN+5];
bool vis[MAXN+5];
bool SPFA(){
queue<int> Q;
for(int i=0;i<=N;i++)
vis[i]=0,dep[i]=INF;
dep[S]=0,vis[S]=1,Q.push(S);
while(!Q.empty()){
int u=Q.front();Q.pop();
vis[u]=0;
for(int i=head[u];~i;i=edge[i].nxt){
double w=edge[i].w;
int v=edge[i].v,cap=edge[i].cap;
if(cap&&dep[v]-(dep[u]+w)>eps){
dep[v]=dep[u]+w;
if(!vis[v])
vis[v]=1,Q.push(v);
}
}
}
return dep[T]<INF;
}
int DFS(int u,int aug){
if(u==T) return aug;
vis[u]=1;
int flow=0,f;
for(int &i=cur[u];~i;i=edge[i].nxt){
int v=edge[i].v,cap=edge[i].cap;double w=edge[i].w;
if(!vis[v]&&abs(dep[v]-(dep[u]+w))<eps&&cap&&(f=DFS(v,min(aug,cap)))){
aug-=f,flow+=f,cost+=f*w;
edge[i].cap-=f,edge[i^1].cap+=f;
if(!aug) break;
}
}
vis[u]=0;
return flow;
}
int Dinic(){
int Max_Flow=0;cost=0;
while(SPFA())
memcpy(cur,head,sizeof(head)),Max_Flow+=DFS(S,INF);
//cost=-cost;
return Max_Flow;
}
struct node{
int x,y;
}a[MAXN+5];
double dis(node a,node b){return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}
int main(){
Init();
int n=read();
for(int i=1;i<=n;i++)
a[i].x=read(),a[i].y=read();
N=2*n+2,S=2*n+1,T=2*n+2;
for(int i=1;i<=n;i++)
Addedge(S,2*i,1,0),Addedge(2*i-1,T,1,0);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(i!=j)
Addedge(2*i,2*j-1,1,dis(a[i],a[j]));
Addedge(S,1,1,0),Addedge(6,T,2,0);
Addedge(S,2,1,0),Addedge(5,T,1,0);
Dinic();
printf("%f\n",cost);
return 0;
}
/*
5
0 0
2 0
3 2
-1 2
1 4
2
0 0
1 1
8
100000 100000
100000 100001
100001 100000
100001 100001
-100000 100000
-100000 100001
-100001 100000
-100001 100001
*/
我解决了NP问题,个屁
猜你喜欢
转载自blog.csdn.net/qq_37555704/article/details/104174891
今日推荐
周排行