Cow Tours(最短路 + Floyd)

本篇介绍了一个关于寻找最优边添加方案的问题,通过Floyd算法预处理所有点对间最短路径,并通过枚举可能的边来确定最优解,以实现两个独立区域连接后的最小直径。
Cow Tours

Farmer John has a number of pastures on his farm. Cow paths connect some pastures with certain other pastures, forming a field. But, at the present time, you can find at least two pastures that cannot be connected by any sequence of cow paths, thus partitioning Farmer John's farm into multiple fields.

Farmer John would like add a single a cow path between one pair of pastures using the constraints below.

A field's `diameter' is defined to be the largest distance of all the shortest walks between any pair of pastures in the field. Consider the field below with five pastures, located at the points shown, and cow paths marked by lines:

                15,15   20,15
                  D       E
                  *-------*
                  |     _/|
                  |   _/  |
                  | _/    |
                  |/      |
         *--------*-------*
         A        B       C
         10,10   15,10   20,10

The `diameter' of this field is approximately 12.07106, since the longest of the set of shortest paths between pairs of pastures is the path from A to E (which includes the point set {A,B,E}). No other pair of pastures in this field is farther apart when connected by an optimal sequence of cow paths.

Suppose another field on the same plane is connected by cow paths as follows:

                         *F 30,15
                         / 
                       _/  
                     _/    
                    /      
                   *------ 
                   G      H
                   25,10   30,10

In the scenario of just two fields on his farm, Farmer John would add a cow path between a point in each of these two fields (namely point sets {A,B,C,D,E} and {F,G,H}) so that the joined set of pastures {A,B,C,D,E,F,G,H} has the smallest possible diameter.

Note that cow paths do not connect just because they cross each other; they only connect at listed points.

The input contains the pastures, their locations, and a symmetric "adjacency" matrix that tells whether pastures are connected by cow paths. Pastures are not considered to be connected to themselves. Here's one annotated adjacency list for the pasture {A,B,C,D,E,F,G,H} as shown above:

                A B C D E F G H
              A 0 1 0 0 0 0 0 0
              B 1 0 1 1 1 0 0 0
              C 0 1 0 0 1 0 0 0
              D 0 1 0 0 1 0 0 0
              E 0 1 1 1 0 0 0 0
              F 0 0 0 0 0 0 1 0
              G 0 0 0 0 0 1 0 1
              H 0 0 0 0 0 0 1 0

Other equivalent adjacency lists might permute the rows and columns by using some order other than alphabetical to show the point connections. The input data contains no names for the points.

The input will contain at least two pastures that are not connected by any sequence of cow paths.

Find a way to connect exactly two pastures in the input with a cow path so that the new combined field has the smallest possible diameter of any possible pair of connected pastures. Output that smallest possible diameter.

PROGRAM NAME: cowtour

INPUT FORMAT

Line 1:An integer, N (1 <= N <= 150), the number of pastures
Line 2-N+1:Two integers, X and Y (0 <= X ,Y<= 100000), that denote that X,Y grid location of the pastures; all input pastures are unique.
Line N+2-2*N+1:lines, each containing N digits (0 or 1) that represent the adjacency matrix as described above, where the rows' and columns' indices are in order of the points just listed.

SAMPLE INPUT (file cowtour.in)

8
10 10
15 10
20 10
15 15
20 15
30 15
25 10
30 10
01000000
10111000
01001000
01001000
01110000
00000010
00000101
00000010

OUTPUT FORMAT

The output consists of a single line with the diameter of the newly joined pastures. Print the answer to exactly six decimal places. Do not perform any special rounding on your output.

SAMPLE OUTPUT (file cowtour.out)

22.071068

 

       题意:

       给出 N(1 ~ 150),代表有 N 个坐标点(X,Y)(0 ~ 100000),后给出 N X N 的邻接矩阵,代表图的连接情况( 0 代表不相连,1 代表相连)。图明确只有两个不相连的连通块,问如何当且仅当增加一条边,使任何点对间的最短路中的最大值最小。输出这个最小数,保留六位小数。

 

       思路:

       最短路 + Floyd。先 Floyd 预处理好所有点对之间的最短路,后枚举两个点,这两个点不相连。增加这条边后,故( 第一个连通块任意两点间的最短路 + 增加边边长 + 第二个连通块任意两点间的最短路) 也为最短路,找到连接后所有点对最短路的最大值。每次枚举的最大值中找一个最小的,当找出这个最小值,还要与原来未连接的时候的最短路的最大值比较。最后得出的这个值即为最终结果的最大值。

 

       AC:

/*
TASK:cowtour
LANG:C++
ID:sum-g1
*/
#include <stdio.h>
#include <string.h>
#include <cmath>
#include <algorithm>
#define INF 99999999
using namespace std;

typedef struct {
    double x,y;
}node;

int n;
node no[155];
double w[155][155];
char state[155][155];
double max_dis;

double dis (double x1,double y1,double x2,double y2) {
    return sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
}

void floyd () {
    for (int k = 1; k <= n; ++k)
            for (int i = 1; i <= n; ++i)
                    for (int j = 1; j <= n; ++j)
                            if(w[i][k] < INF &&
                               w[k][j] < INF &&
                               w[i][j] > w[i][k] + w[k][j])
                               w[i][j] = w[i][k] + w[k][j];
}

void init () {
    for (int i = 1; i <= n; ++i)
            for (int j = 1; j <= n; ++j) {
                    if (state[i][j] == '1')
                        w[i][j] =
                        dis(no[i].x,no[i].y,no[j].x,no[j].y);
                    else w[i][j] = INF;
                    if(i == j) w[i][j] = 0;
            }
}

double make_max (int s,int e,double dis) {
    double max_now = -1;
    for (int i = 1; i <= n; ++i)
            for (int j = 1; j <= n; ++j)
                    if(w[i][s] < INF &&
                       w[e][j] < INF)
                       max_now = max(max_now,w[i][s] + w[e][j] + dis);

    return max_now;
}

int main() {
    freopen("cowtour.in","r",stdin);
    freopen("cowtour.out","w",stdout);

    scanf("%d",&n);
    for (int i = 1; i <= n; ++i)
            scanf("%lf%lf",&no[i].x,&no[i].y);

    for (int i = 1; i <= n; ++i) {
            for (int j = 1; j <= n; ++j)
                    scanf(" %c",&state[i][j]);
    }

    init();
    floyd();

    max_dis = -1;
    for (int i = 1; i <= n; ++i)
            for (int j = 1; j <= n; ++j)
                    if(w[i][j] < INF)
                    max_dis = max(max_dis,w[i][j]);

    double min_dis = INF;
    for (int i = 1; i <= n; ++i)
            for (int j = 1; j <= n; ++j)
                    if(w[i][j] == INF) {
                            double change = dis(no[i].x,no[i].y,no[j].x,no[j].y);
                            min_dis = min(min_dis,make_max(i,j,change));
                    }
    min_dis = max(min_dis,max_dis);

    printf("%f\n",min_dis);
    return 0;
}

 

 

基于遗传算法的微电网调度(风、光、蓄电池、微型燃气轮机)(Matlab代码实现)内容概要:本文档介绍了基于遗传算法的微电网调度模型,涵盖风能、太阳能、蓄电池和微型燃气轮机等多种能源形式,并通过Matlab代码实现系统优化调度。该模型旨在解决微电网中多能源协调运行的问题,优化能源分配,降低运行成本,提高可再生能源利用率,同时考虑系统稳定性与经济性。文中详细阐述了遗传算法在求解微电网多目标优化问题中的应用,包括编码方式、适应度函数设计、约束处理及算法流程,并提供了完整的仿真代码供复现与学习。此外,文档还列举了大量相关电力系统优化案例,如负荷预测、储能配置、潮流计算等,展示了广泛的应用背景和技术支撑。; 适合人群:具备一定电力系统基础知识和Matlab编程能力的研究生、科研人员及从事微电网、智能电网优化研究的工程技术人员。; 使用场景及目标:①学习遗传算法在微电网调度中的具体实现方法;②掌握多能源系统建模与优化调度的技术路线;③为科研项目、毕业设计或实际工程提供可复用的代码框架与算法参考; 阅读建议:建议结合Matlab代码逐段理解算法实现细节,重点关注目标函数构建与约束条件处理,同时可参考文档中提供的其他优化案例进行拓展学习,以提升综合应用能力。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值