图论训练之一

Posted wzxbeliever

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了图论训练之一相关的知识,希望对你有一定的参考价值。

noip水题系列

https://www.luogu.org/problem/P1027

题目明显就是一个多组数据(也就<=10)单源最短路,

这里可以就不用floyed

但你会发现它是道蓝题也是有一定道理的

你会很恼火它的建边:

使用勾股定理加一系列的特判,而且又是浮点数

话不多述,

思路简单,代码麻烦,就把题解修改一下搬过来了

code:

#include <cstdio>
#include <cmath>
#include <cstring>
#include <queue>
using namespace std;
struct data 
    int x,y;
    int city; 
;
const int maxn=100;
int s,t,A,B;
int T[maxn+1];
double dis[maxn<<2|1];
data a[maxn<<2|1];
int pingfang(int x)  return x*x; 
double juli(int x1, int y1, int x2, int y2)  return sqrt(pingfang(x1-y1)+pingfang(x2-y2)); 
void get_4th(int x1, int y1, int x2, int y2, int x3, int y3, int i) 
    int ab=pingfang(x1-x2)+pingfang(y1-y2),
        ac=pingfang(x1-x3)+pingfang(y1-y3),
        bc=pingfang(x2-x3)+pingfang(y2-y3);
    int x4,y4;
    if (ab+ac==bc) x4=x2+x3-x1, y4=y2+y3-y1;
    if (ab+bc==ac) x4=x1+x3-x2, y4=y1+y3-y2;
    if (ac+bc==ab) x4=x1+x2-x3, y4=y1+y2-y3;
    a[i+3].x=x4;
    a[i+3].y=y4;

void init() 
    memset(a,0,sizeof(a));
    scanf("%d%d%d%d",&s,&t,&A,&B);
    for (int i=1; i<=4*s; i+=4) 
        scanf("%d%d%d%d%d%d%d",&a[i].x,&a[i].y,&a[i+1].x,&a[i+1].y,&a[i+2].x,&a[i+2].y,&T[i/4+1]);
        a[i].city=a[i+1].city=a[i+2].city=a[i+3].city=i/4+1;
        get_4th(a[i].x,a[i].y,a[i+1].x,a[i+1].y,a[i+2].x,a[i+2].y,i);
    

void spfa()  
    bool mark[maxn<<2|1];
    queue <int> q;
    for (int i=1; i<=4*s; i++) dis[i]=99999999.99999;
    for (int i=A*4-3;i<=A*4;i++)
        dis[i]=0, q.push(i), mark[i]=true;
    while (!q.empty()) 
        int x=q.front(); q.pop(); mark[x]=false;
        for (int i=1; i<=4*s; i++) 
            if (i==x) continue;
            double cost=juli(a[x].x,a[i].x,a[x].y,a[i].y);
            if (a[i].city==a[x].city) cost*=T[a[i].city];
            else cost*=t;
            if (dis[x]+cost<dis[i]) 
                dis[i]=dis[x]+cost;
                if (!mark[i])
                    mark[i]=true, q.push(i);
            
        
    


int main() 
    int n;
    scanf("%d",&n);
    while (n--) 
        init();
        spfa();
        double ans=dis[B*4];
        for (int i=B*4-3; i<B*4; i++)
            if (dis[i]<ans) ans=dis[i];
        printf("%.1lf",ans);
    

以上是关于图论训练之一的主要内容,如果未能解决你的问题,请参考以下文章

图论训练之二

图论训练

联合训练图论场

图论专题训练 (更新中)

图论训练之四

图论训练之七