帝国布线 十分恶心的加边图论题
分析?
看见这题第一眼,这什么鬼??看不懂。/
还好有万能的老师,解释一通后大概明白了,这不就是最短路??于是准备大展身手瞎打一下试试 , 写输入的时候我犹豫了,emm,貌似只有三个点?还是任意的三个点?哇那这很难受啊,所以这道题其实最难的地方是什么,求出第四个点的坐标,由三个任意点可以想到什么呢,三角形,三角形是什么?矩形的一半,所以枚举三角形的三条边,最长的那一条就是矩形对角线,对角线的两端已经确定,可以求出对角线中点,中点有了,剩下的那个点也就好求了(感谢初中数学老师)。
然后就跑一个最短路就行了,看数据范围好像Floyd也可以,但不敢用,万一炸了那不就gg?图中没有负权,所以写了一个Dij,有一个点注意下就是一座城市有四个出发点,所以可以跑四遍Dij,但这样是不是很麻烦,所以我建了一个超级源点,让这个点到四个点的距离为0,然后从这个点开始最短路,最后看看到B的那个点最短输出就行。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<queue> 3 #include<cmath> 4 #include<cstring> 5 #include<algorithm> 6 using namespace std; 7 typedef double d; 8 const int N=1e5+10; 9 const d INF=0x3f3f3f3f; 10 struct Edge{ 11 int to,next; 12 d val; 13 }e[N]; 14 struct Node{ 15 d x,y; 16 }p[N]; 17 int Head[N],len,num; 18 void Ins(int a,int b,d c){ 19 e[++len].to=b;e[len].val=c; 20 e[len].next=Head[a];Head[a]=len; 21 } 22 d dis(d x,d y,d xx,d yy){ 23 return sqrt((x-xx)*(x-xx)+(y-yy)*(y-yy)); 24 } 25 d X1,Y1,X2,Y2,X3,Y3,X4,Y4,dist[N]; 26 void point(){ 27 d a=dis(X1,Y1,X2,Y2), 28 b=dis(X1,Y1,X3,Y3), 29 c=dis(X2,Y2,X3,Y3); 30 d Max=max(a,max(b,c)); 31 d mix,miy,mxx,mxy,x,y; 32 if(Max==a)mix=X1,miy=Y1,mxx=X2,mxy=Y2,x=X3,y=Y3; 33 if(Max==b)mix=X1,miy=Y1,mxx=X3,mxy=Y3,x=X2,y=Y2; 34 if(Max==c)mix=X2,miy=Y2,mxx=X3,mxy=Y3,x=X1,y=Y1; 35 d midx=(mix+mxx)/2,midy=(miy+mxy)/2; 36 X4=2*midx-x;Y4=2*midy-y; 37 } 38 d ans,m,belong[N];int fro,tto,n;bool vis[N]; 39 void init(){ 40 len=num=0; 41 ans=INF; 42 memset(Head,0,sizeof(Head)); 43 memset(belong,0,sizeof(belong)); 44 memset(p,0,sizeof(p)); 45 memset(vis,0,sizeof(vis)); 46 } 47 struct node{ 48 int id;d diss; 49 node(){} 50 node(int a,d b){ 51 id=a;diss=b; 52 } 53 bool operator < (const node &A)const { 54 return diss>A.diss; 55 } 56 }; 57 void dij(){ 58 priority_queue<node> q; 59 q.push(node(0,0)); 60 dist[0]=0; 61 while(!q.empty()){ 62 node u=q.top();q.pop(); 63 if(vis[u.id])continue; 64 vis[u.id]=1; 65 for(int x=Head[u.id];x;x=e[x].next){ 66 int v=e[x].to; 67 if(dist[v]>dist[u.id]+e[x].val){ 68 dist[v]=dist[u.id]+e[x].val; 69 q.push(node(v,dist[v])); 70 } 71 } 72 } 73 } 74 int main(){ 75 freopen("car.in","r",stdin); 76 freopen("car.out","w",stdout); 77 int t; 78 scanf("%d",&t); 79 while(t--){ 80 init(); 81 scanf("%d%lf%d%d",&n,&m,&fro,&tto); 82 for(int i=1;i<=n;i++){ 83 scanf("%lf%lf%lf%lf%lf%lf%lf",&X1,&Y1,&X2,&Y2,&X3,&Y3,&belong[i]); 84 point(); 85 p[++num].x=X1,p[num].y=Y1; 86 p[++num].x=X2,p[num].y=Y2; 87 p[++num].x=X3,p[num].y=Y3; 88 p[++num].x=X4,p[num].y=Y4; 89 } 90 for(int i=1;i<=num;i++) 91 dist[i]=INF; 92 for(int i=1;i<=num;i++){ 93 for(int j=1;j<=num;j++){ 94 if(i==j)continue; 95 int c1=(i-1>>2)+1,c2=(j-1>>2)+1; 96 if(c1==c2){ 97 d c=dis(p[i].x,p[i].y,p[j].x,p[j].y)*belong[c1]; 98 Ins(i,j,c); 99 Ins(j,i,c); 100 }else { 101 d c=dis(p[i].x,p[i].y,p[j].x,p[j].y)*m; 102 Ins(i,j,c); 103 Ins(j,i,c); 104 } 105 } 106 } 107 for(int i=(fro-1<<2)+1;i<=fro<<2;i++){ 108 Ins(0,i,0);Ins(i,0,0); 109 } 110 dij(); 111 for(int i=(tto-1<<2)+1;i<=tto<<2;i++)ans=min(dist[i],ans); 112 printf("%.1lf\n",ans); 113 } 114 return 0; 115 }
由于太长了所以我直接折叠了吧。。
超级喜欢太阳 PS:图片来源zsy
int - > long long
0 - > 100