又到暑假了,住在城市 A 的 Car 想和朋友一起去城市旅游。
她知道每个城市都有 4 个飞机场,分别位于一个矩形的 4 个顶点上,同一个城市中两个机场之间有一条笔直的高速铁路,第 i 个城市中高速铁路的单位里程价格为 Ti,任意两个不同城市的机场之间均有航线,所有航线单位里程的价格均为 t。
注意:图中并没有标出所有的铁路与航线。
那么 Car 应如何安排到城市 B 的路线才能尽可能的节省花费呢?她发现这并不是一个简单的问题,于是她来向你请教。
找出一条从城市 A 到 B 的旅游路线,出发和到达城市中的机场可以任意选取,要求总的花费最少。
第一行为一个正整数 n,表示有 n 组测试数据。
每组的第一行有 4 个正整数 S,t,A,B。
S 表示城市的个数,t 表示飞机单位里程的价格,A,B 分别为城市A,B 的序号。
接下来有 S 行,其中第 i 行均有 7 个正整数xi1,yi1,xi2,yi2,xi3,yi3,Ti,这当中的 (xi1,yi1),(xi2,yi2),(xi3,yi3),分别是第 i 个城市中任意 3 个机场的坐标,Ti 为第 i 个城市高速铁路单位里程的价格。
共有 n 行,每行 1 个数据对应测试数据。
保留一位小数。
输入 #1
1
3 10 1 3
1 1 1 3 3 1 30
2 5 7 4 5 2 1
8 6 8 8 11 6 3
输出 #1
47.5
【数据范围】
对于 100% 的数据,1≤n≤10,1≤S≤100,1≤A,B≤S。
【题目来源】
NOIP 2001 提高组第四题
#include
#define ll long long
using namespace std;
const ll N=4e5;
ll x[105][6],z[105],tot,y[105][6],h[N],ne[N],to[N];
double w[N],dp[N];
ll s,t,a,b,p;
bool vis[N];
void add(ll a,ll b,double c)
{
tot++;
ne[tot]=h[a];
h[a]=tot;
to[tot]=b;
w[tot]=c;
}
void qiu(ll g,ll x1,ll x2,ll x3,ll y1,ll y2,ll y3)
{double x4,y4;x4=(x2+x3);y4=(y2+y3);x[g][4]=x4-x1;y[g][4]=y4-y1;}
void find(ll g)
{ ll x1,x2,x3,y1,y2,y3;
x1=x[g][1];x2=x[g][2];x3=x[g][3];y1=y[g][1];y2=y[g][2];y3=y[g][3];
if(y1==y2){if(x2==x3){x[g][4]=x1;y[g][4]=y3;return; }else {x[g][4]=x2;y[g][4]=y3;return; } }
if(y1==y3){if(x2==x3){x[g][4]=x1;y[g][4]=y2;return; }else { x[g][4]=x3;y[g][4]=y2;return; } }
if(y2==y3){if(x1==x3){x[g][4]=x2;y[g][4]=y1;return;}else {x[g][4]=x3;y[g][4]=y1;return; } }
if((y2-y1)*(y1-y3)/((x1-x3)*(x2-x1))==-1) qiu(g,x1,x2,x3,y1,y2,y3);
if((y3-y2)*(y2-y1)/((x2-x1)*(x3-x2))==-1) qiu(g,x2,x1,x3,y2,y1,y3);
if((y2-y3)*(y3-y1)/((x3-x1)*(x2-x3))==-1) qiu(g,x3,x2,x1,y3,y2,y1);
}
double dfs(ll a,ll b,ll c,ll d)
{
ll x1,x2,y1,y2;x1=x[a][b];y1=y[a][b];x2=x[c][d];y2=y[c][d];
return sqrt(abs(x1-x2)*abs(x1-x2)+abs(y1-y2)*abs(y1-y2));
}
void spfa(ll d,ll h1)
{
memset(vis,0,sizeof(vis));
for(ll i=5;i<=s*4+4;i++)
dp[i]=0x7fffffff;
dp[d*4+h1]=0.0;
vis[d*4+h1]=1;
queueq;
q.push(d*4+h1);
while(!q.empty())
{
ll j=q.front();q.pop();vis[j]=0;
for(ll i=h[j];i;i=ne[i])
{
ll jj=to[i];
if(dp[jj]>dp[j]+w[i])
{
dp[jj]=dp[j]+w[i];
if(!vis[jj])
{
vis[jj]=1;
q.push(jj);
}
}
}
}
}
int main()
{
//ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
cin>>p;
for(int i=1;i<=p;i++)
{
memset(h,0,sizeof(h));
memset(ne,0,sizeof(ne));
cin>>s>>t>>a>>b;
for(ll i=1;i<=s;i++)
{
for(ll j=1;j<=3;j++)
cin>>x[i][j]>>y[i][j];
cin>>z[i];
find(i);
}
for(ll i=1;i<=s;i++)
for(ll k=1;k<=4;k++)
{
for(ll j=1;j<=k-1;j++)
add(4*i+k,4*i+j,dfs(i,k,i,j)*1.0*z[i]);
for(ll j=k+1;j<=4;j++)
add(4*i+k,4*i+j,dfs(i,k,i,j)*1.0*z[i]);
}
for(ll i=1;i<=s;i++)
for(ll k=1;k<=4;k++)
for(ll r=1;r<=4;r++)
{
for(ll j=1;j<=i-1;j++)
add(4*i+k,4*j+r,dfs(i,k,j,r)*1.0*t);
for(ll j=i+1;j<=s;j++)
add(4*i+k,4*j+r,dfs(i,k,j,r)*1.0*t);
}
double minn=0x7fffffff;
for(ll i=1;i<=4;i++)
{
spfa(a,i);
for(ll j=1;j<=4;j++)
minn=min(minn,dp[b*4+j]);
}
printf("%0.1lf",minn);
}
return 0;
}