标签: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