NC16697 Car的旅行路线 &P1027 [NOIP2001 提高组] Car 的旅行路线 ——注意!理解错题意,导致wa了几十发

题解:

这道题两步: 建图+Dijstra
难点: 建图

  • 对于同一个城市的4个飞机场,两两之间都应该建一条路,w=dist*city[i].T, 我最先一直以为只有矩阵的四条边。。。,一直wa
  • 不同城市之间的飞机场,两两之间建一条路,w=dist*t
  • 求第四个点:这里不多赘述,利用平行四边形性质即可,参考大佬博客洛谷大佬

AC代码

#include<bits/stdc++.h>

using namespace std;
#define N 109
#define M 160000+9 
#define mem(a,b) memset(a,b,sizeof a)
#define PII pair<double,double>
#define PII2 pair<double ,int>
int e[M],ne[M],h[M],idx,cnt;
double w[M];
map<PII,int> mp;
const double eps = 1e-8;
double dist[M];
bool st[M];
double s,t,A,B; //城市个数 ,飞机单位历程价格
//A,B分别表示城市A B的序号 
int s1,e1;
struct node
{
	double x[6],y[6],T;
}city[N];
void add(int x,int y,double z)
{
	e[idx] = y;
	w[idx] = z;
	ne[idx] = h[x];
	h[x] = idx++;
}
void Dijstra()
{
	for(int i=1; i<=M; i++) dist[i] = DBL_MAX; 
	mem(st,false); 
	dist[s1] = 0,dist[s1+1] = 0,dist[s1+2]=0, dist[s1+3]=0;
	priority_queue<PII2,vector<PII2> ,greater<PII2> > heap;
	heap.push({0,s1}),heap.push({0,s1+1}),heap.push({0,s1+2}),heap.push({0,s1+3});
	while(heap.size())
	{
		PII2 tmp = heap.top();
		heap.pop();
        double d= tmp.first;
        int p = tmp.second;
		if(st[p]) continue;
		st[p] = true;
		for(int i=h[p]; i!=-1; i=ne[i])
		{
			int j = e[i];
			if(dist[j] > d+w[i])
			{
				dist[j] = d+w[i];
				heap.push({dist[j],j}); 
			}
		}
	}
}
double Dist(double x1,double y1,double x2,double y2)
{
	return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
} 
int main()
{
	
	int n;
	cin>>n;
	while(n--)
 	{
 		mp.clear();
 		//cout<<mp.size()<<" mp"<<endl;
 		mem(h,-1);
 		mem(e,0);
 		mem(ne,0);
 		mem(w,0);
 		idx=0;
 		s1=e1=cnt=0;
 		cin>>s>>t>>A>>B;
 		for(int i=1; i<=s; i++)
 		{
 			for(int j=1; j<=3; j++)
 			{
 				cin>>city[i].x[j]>>city[i].y[j];
 				if(!mp[{city[i].x[j],city[i].y[j]}])
				 mp[{city[i].x[j],city[i].y[j]}] = ++cnt;
				if(i==A&&!s1) s1=cnt;
				if(i==B&&!e1) e1 = cnt;
			}
			cin>>city[i].T;
			double x1 = city[i].x[1],y1 = city[i].y[1],x2 =city[i].x[2],y2 = city[i].y[2];
			double x3  =city[i].x[3],y3 = city[i].y[3],x4,y4;
			double  a = Dist(x1,y1 ,x2,y2);
			double  b = Dist(x2,y2, x3,y3);
			double  c = Dist(x3,y3, x1,y1);
			if(a*a+b*b-c*c<eps) { 
			city[i].x[4]=x4 = x1+x3-x2; 
			city[i].y[4] = y4 = y1+y3-y2; 
			}
			if(a*a+c*c-b*b<eps) { 
			city[i].x[4]=x4 = x2+x3-x1;
			city[i].y[4] = y4=y2+y3-y1;
			}
			if(b*b+c*c-a*a<eps) { 
				city[i].x[4]= x4= x1+x2-x3; 
				city[i].y[4] = y4=y1+y2-y3;
			}	
			if(!mp[{x4,y4}]) mp[{x4,y4}] = ++cnt;
    }
    //各个城市之间的机场路线建图 
    for(int i=1; i<=s; i++)
    {
    	for(int j=i; j<=s; j++)
    	{
    		for(int k=1 ;k<=4; k++)
    		{
    			for(int l=1; l<=4; l++)
    			{
    				int u = mp[{city[i].x[k],city[i].y[k]}];
    				int v = mp[{city[j].x[l],city[j].y[l]}];
    				double d;
    				if(i==j) d = city[i].T*Dist(city[i].x[k],city[i].y[k],city[j].x[l],city[j].y[l]);
    				else  d = t*Dist(city[i].x[k],city[i].y[k],city[j].x[l],city[j].y[l]);
    				add(u,v,d);
    				add(v,u,d);
				}
			}
		}
	}
	//cout<<s1<<" "<<e1<<endl;
	double ans = DBL_MAX;
	Dijstra();
	for(int i=e1; i<=e1+3; i++) 
	{
		ans  = min(ans,dist[i]);
	}
	printf("%.1f\n",ans);
}
	return 0;
 } 

wa代码

对于同一个城市,我只建立了四条边,即矩阵的四条边

#include<bits/stdc++.h>

using namespace std;
#define N 109
#define M 160000+9 
#define mem(a,b) memset(a,b,sizeof a)
#define PII pair<double,double>
#define PII2 pair<double ,int>
int e[M],ne[M],h[M],idx,cnt;
double w[M];
map<PII,int> mp;
const double eps = 1e-8;
double dist[M];
bool st[M];
double s,t,A,B; //城市个数 ,飞机单位历程价格
//A,B分别表示城市A B的序号 
int s1,e1;
struct node
{
	double x[6],y[6],T;
}city[N];
void add(int x,int y,double z)
{
	e[idx] = y;
	w[idx] = z;
	ne[idx] = h[x];
	h[x] = idx++;
}
void Dijstra()
{
	for(int i=1; i<=M; i++) dist[i] = DBL_MAX; 
	mem(st,false); 
	dist[s1] = 0,dist[s1+1] = 0,dist[s1+2]=0, dist[s1+3]=0;
	priority_queue<PII2,vector<PII2> ,greater<PII2> > heap;
	heap.push({0,s1}),heap.push({0,s1+1}),heap.push({0,s1+2}),heap.push({0,s1+3});
	while(heap.size())
	{
		PII2 tmp = heap.top();
		heap.pop();
        double d= tmp.first;
        int p = tmp.second;
		if(st[p]) continue;
		st[p] = true;
		for(int i=h[p]; i!=-1; i=ne[i])
		{
			int j = e[i];
			if(dist[j] > d+w[i])
			{
				dist[j] = d+w[i];
				heap.push({dist[j],j}); 
			}
		}
	}
}
double Dist(double x1,double y1,double x2,double y2)
{
	return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
} 
int main()
{
	
	int n;
	cin>>n;
	while(n--)
 	{
 		mp.clear();
 		//cout<<mp.size()<<" mp"<<endl;
 		mem(h,-1);
 		mem(e,0);
 		mem(ne,0);
 		mem(w,0);
 		mem(city,0);
 		idx=0;
 		s1=e1=cnt=0;
 		cin>>s>>t>>A>>B;
 		for(int i=1; i<=s; i++)
 		{
 			for(int j=1; j<=3; j++)
 			{
 				cin>>city[i].x[j]>>city[i].y[j];
 				if(!mp[{city[i].x[j],city[i].y[j]}])
				 mp[{city[i].x[j],city[i].y[j]}] = ++cnt;
				if(i==A&&!s1) s1=cnt;
				if(i==B&&!e1) e1 = cnt;
			}
			cin>>city[i].T;
			double x1 = city[i].x[1],y1 =city[i].y[1],x2 =city[i].x[2],y2 = city[i].y[2];
			double x3  =city[i].x[3],y3 = city[i].y[3],x4,y4;
			double  a = Dist(x1,y1 ,x2,y2);
			double  b = Dist(x2,y2, x3,y3);
			double  c = Dist(x3,y3, x1,y1);
			if(a*a+b*b-c*c<eps) { 
			city[i].x[4]=x4 = x1+x3-x2; 
			city[i].y[4] = y4 = y1+y3-y2; 
			if(!mp[{x4,y4}]) mp[{x4,y4}] = ++cnt;
			add(mp[{x1,y1}],mp[{x2,y2}],a*city[i].T);
			add(mp[{x2,y2}],mp[{x1,y1}],a*city[i].T);
			add(mp[{x2,y2}],mp[{x3,y3}],b*city[i].T);
			add(mp[{x3,y3}],mp[{x2,y2}],b*city[i].T);
	        add(mp[{x1,y1}],mp[{x4,y4}],b*city[i].T);
	        add(mp[{x4,y4}],mp[{x1,y1}],b*city[i].T);
	        add(mp[{x4,y4}],mp[{x3,y3}],a*city[i].T);
	        add(mp[{x3,y3}],mp[{x4,y4}],a*city[i].T);
			}
			if(a*a+c*c-b*b<eps) { 
			city[i].x[4]=x4 = x2+x3-x1;
			city[i].y[4] = y4=y2+y3-y1;
			if(!mp[{x4,y4}]) mp[{x4,y4}] = ++cnt;
	    	add(mp[{x1,y1}],mp[{x2,y2}],a*city[i].T);
			add(mp[{x2,y2}],mp[{x1,y1}],a*city[i].T);
			add(mp[{x3,y3}],mp[{x4,y4}],a*city[i].T);
			add(mp[{x4,y4}],mp[{x3,y3}],a*city[i].T);
			add(mp[{x1,y1}],mp[{x3,y3}],c*city[i].T);
			add(mp[{x3,y3}],mp[{x1,y1}],c*city[i].T);
			add(mp[{x2,y2}],mp[{x4,y4}],c*city[i].T);
			add(mp[{x4,y4}],mp[{x2,y2}],c*city[i].T);
			}
			if(b*b+c*c-a*a<eps) { 
				city[i].x[4]= x4= x1+x2-x3; 
				city[i].y[4] = y4=y1+y2-y3;
			if(!mp[{x4,y4}]) mp[{x4,y4}] = ++cnt;
	    	add(mp[{x1,y1}],mp[{x4,y4}],b*city[i].T);
			add(mp[{x4,y4}],mp[{x1,y1}],b*city[i].T);
			add(mp[{x3,y3}],mp[{x2,y2}],b*city[i].T);
			add(mp[{x2,y2}],mp[{x3,y3}],b*city[i].T);
			add(mp[{x1,y1}],mp[{x3,y3}],c*city[i].T);
			add(mp[{x3,y3}],mp[{x1,y1}],c*city[i].T);
			add(mp[{x2,y2}],mp[{x4,y4}],c*city[i].T);
			add(mp[{x4,y4}],mp[{x2,y2}],c*city[i].T);
			}	
    }
    //各个城市之间的机场路线建图 
    for(int i=1; i<=s; i++)
    {
    	for(int j=1; j<=s; j++)
    	{
    		for(int k=1 ;k<=4; k++)
    		{
    			for(int l=1; l<=4; l++)
    			{
    				if(i==j) continue;
    				int u = mp[{city[i].x[k],city[i].y[k]}];
    				int v = mp[{city[j].x[l],city[j].y[l]}];
    				double d = t*Dist(city[i].x[k],city[i].y[k],city[j].x[l],city[j].y[l]);
    				//cout<<u<<" "<<v<<" "<<d<<endl; 
    				add(u,v,d);
    				add(v,u,d);
				}
			}
		}
	}
	//cout<<s1<<" "<<e1<<endl;
	double ans = DBL_MAX;
	Dijstra();
	for(int i=e1; i<=e1+3; i++) ans = min(ans,dist[i]);
	printf("%.1f\n",ans);
}
	return 0;
 } 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值