我解决了NP问题,个屁

#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

*/

猜你喜欢

转载自blog.csdn.net/qq_37555704/article/details/104174891