标签:des style http color java os io strong
2 4 1 0 0 2 0 1 1 1 -1 1 1 -3 -1 5 1 2 4 2 0 0 2 0 1 2 1 -1 1 1 -3 -1 5 1
10.472135955000 16.944271909999
题意:
有n颗树,总共有k种种类,每棵树有一个种类,有m个木桩,要选一些木桩连起来,使得包含所有的树的种类,并且连线最短。
由于k<=6,数据很小,一看就是状压dp, 把m个点的三角形全部找出来,然后把三角形内部k个种类的状态全部找出来,然后就是三角形合并,每次合并都会是
两边的周长减去公共边的长度的2倍,然后状态合并,
用类似与最短路的方法求答案。
搞了半天,发现spfa有问题,我们需要记录k的状态,还需要记录当前周长的状态,由于一个状态可能有多个周长,用数组记录也不大方便,所以把它拧成一个节点,丢进优先队列里,这样合并就没问题了,
代码:
/* ***********************************************
Author :rabbit
Created Time :2014/8/15 10:13:28
File Name :5.cpp
************************************************ */
#pragma comment(linker, "/STACK:102400000,102400000")
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <string>
#include <time.h>
#include <math.h>
#include <queue>
#include <stack>
#include <set>
#include <map>
using namespace std;
#define INF 1e15
#define eps 1e-9
#define pi acos(-1.0)
typedef long long ll;
int dcmp(double x){
if(fabs(x)<eps)return 0;
return x>0?1:-1;
}
struct Point{
double x,y;
Point(double _x=0,double _y=0){
x=_x;
y=_y;
}
};
Point operator + (Point a,Point b){
return Point(a.x+b.x,a.y+b.y);
}
Point operator - (Point a,Point b){
return Point(a.x-b.x,a.y-b.y);
}
double dist(Point a,Point b){
double ss=a.x-b.x;
double tt=a.y-b.y;
return sqrt(ss*ss+tt*tt);
}
double Cross(Point a,Point b){
return a.x*b.y-a.y*b.x;
}
int tot,id[40][40][40],state[11010];
int getid(int a,int b,int c){
if(b>c)swap(b,c);
if(a>b)swap(a,b);
if(b>c)swap(b,c);
return id[a][b][c];
}
int head[11010],tol;
struct Edge{
int next,to;
double val;
}edge[2002000];
void addedge(int u,int v,double val){
edge[tol].to=v;
edge[tol].val=val;
edge[tol].next=head[u];
head[u]=tol++;
}
double dp[11010][1<<6];
int vis[10010][1<<6];
Point p1[400],p2[400];
int dd[500];
double A[100100];
bool check(Point a,Point b,Point c,Point d){
double t1=fabs(Cross(a-d,b-d));
double t2=fabs(Cross(a-d,c-d));
double t3=fabs(Cross(b-d,c-d));
double t4=fabs(Cross(b-a,c-a));
if(dcmp(t4-t3-t2-t1)==0)return true;
return false;
}
int main()
{
//freopen("data.in","r",stdin);
//freopen("data.out","w",stdout);
int N,M,K;
while(cin>>N>>M>>K){
memset(head,-1,sizeof(head));tol=0;
tot=0;
for(int i=1;i<=N;i++)cin>>p1[i].x>>p1[i].y;
for(int i=1;i<=N;i++)cin>>dd[i],dd[i]--;
for(int i=1;i<=M;i++)cin>>p2[i].x>>p2[i].y;
for(int i=1;i<=M;i++)
for(int j=i+1;j<=M;j++)
for(int k=j+1;k<=M;k++)
id[i][j][k]=++tot;
// cout<<"tot="<<tot<<endl;
memset(state,0,sizeof(state));
for(int i=1;i<=M;i++)
for(int j=i+1;j<=M;j++)
for(int k=j+1;k<=M;k++)
for(int a=1;a<=N;a++)
if(check(p2[i],p2[j],p2[k],p1[a]))state[id[i][j][k]]|=(1<<dd[a]);
//cout<<"state: ";for(int i=1;i<=tot;i++)cout<<state[i]<<" ";cout<<endl;
for(int i=1;i<=M;i++)
for(int j=i+1;j<=M;j++)
for(int k=j+1;k<=M;k++){
double val=dist(p2[i],p2[j])+dist(p2[i],p2[k])+dist(p2[j],p2[k]);
addedge(0,id[i][j][k],0);
A[id[i][j][k]]=val;
}
for(int i=1;i<=M;i++)
for(int j=i+1;j<=M;j++)
for(int k=j+1;k<=M;k++)
for(int t=1;t<=M;t++){
if(t==i||t==j||t==k)continue;
int s1=id[i][j][k],s2;
double t1,t2;
t1=Cross(p2[j]-p2[i],p2[k]-p2[i]);t2=Cross(p2[j]-p2[i],p2[t]-p2[i]);//i,j共边。
if(dcmp(t1)*dcmp(t2)<0)addedge(s1,getid(i,j,t),-2*dist(p2[i],p2[j]));
t1=Cross(p2[k]-p2[i],p2[t]-p2[i]);t2=Cross(p2[k]-p2[i],p2[j]-p2[i]);//i,k共边
if(dcmp(t1)*dcmp(t2)<0)addedge(s1,getid(i,k,t),-2*dist(p2[i],p2[k]));
t1=Cross(p2[k]-p2[j],p2[t]-p2[j]);t2=Cross(p2[k]-p2[j],p2[i]-p2[j]);//j,k共边
if(dcmp(t1)*dcmp(t2)<0)addedge(s1,getid(j,k,t),-2*dist(p2[j],p2[k]));
}
//cout<<"edge: "; for(int i=0;i<tol;i++)cout<<edge[i].val<<endl;
for(int i=0;i<=tot;i++)
for(int j=0;j<(1<<K);j++)
dp[i][j]=INF;
if(ans<INF)printf("%.12lf\n",ans);
else puts("Impossible");
}
//Point a,b,c,d;while(cin>>a.x>>a.y>>b.x>>b.y>>c.x>>c.y>>d.x>>d.y)cout<<check(a,b,c,d)<<endl;
return 0;
}
标签:des style http color java os io strong
原文地址:http://blog.csdn.net/xianxingwuguan1/article/details/38583455