Highways 和Arctic Network 最小生成树

The island nation of Flatopia is perfectly flat. Unfortunately, Flatopia has a very poor system of public highways. The Flatopian government is aware of this problem and has already constructed a number of highways connecting some of the most important towns. However, there are still some towns that you can’t reach via a highway. It is necessary to build more highways so that it will be possible to drive between any pair of towns without leaving the highway system.

Flatopian towns are numbered from 1 to N and town i has a position given by the Cartesian coordinates (xi, yi). Each highway connects exaclty two towns. All highways (both the original ones and the ones that are to be built) follow straight lines, and thus their length is equal to Cartesian distance between towns. All highways can be used in both directions. Highways can freely cross each other, but a driver can only switch between highways at a town that is located at the end of both highways.

The Flatopian government wants to minimize the cost of building new highways. However, they want to guarantee that every town is highway-reachable from every other town. Since Flatopia is so flat, the cost of a highway is always proportional to its length. Thus, the least expensive highway system will be the one that minimizes the total highways length.
Input
The input consists of two parts. The first part describes all towns in the country, and the second part describes all of the highways that have already been built.

The first line of the input file contains a single integer N (1 <= N <= 750), representing the number of towns. The next N lines each contain two integers, xi and yi separated by a space. These values give the coordinates of ith town (for i from 1 to N). Coordinates will have an absolute value no greater than 10000. Every town has a unique location.

The next line contains a single integer M (0 <= M <= 1000), representing the number of existing highways. The next M lines each contain a pair of integers separated by a space. These two integers give a pair of town numbers which are already connected by a highway. Each pair of towns is connected by at most one highway.
Output
Write to the output a single line for each new highway that should be built in order to connect all towns with minimal possible total length of new highways. Each highway should be presented by printing town numbers that this highway connects, separated by a space.

If no new highways need to be built (all towns are already connected), then the output file should be created but it should be empty.
Sample Input
9
1 5
0 0
3 2
4 5
5 1
0 4
5 2
1 2
5 3
3
1 3
9 7
1 2
Sample Output
1 6
3 7
4 9
5 7
8 3
题目大意:给你 n 个城镇的坐标,给你 m 个条路,这 m 条路是已经连接 n 个城镇的路,让我们建立路使每两个城镇之间是可以相互到达的,且我们搭建的路要达到路径和最小,每搭建一条路就输出这条路的起点和终点;
其实这就是一个模板题,就是在记录到达每个点的最短路径的同时记录是哪个点到达该点路径最短;

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
const int N=1e4+5,inf=0x3f3f3f3f;
int vis[N],n,sum,first[N];
double map[N][N],dist[N];
struct node
{
    double x,y;
} a[N];
double can(int i,int j)
{
    double v,u,z;
    v=abs(a[i].x-a[j].x)*abs(a[i].x-a[j].x);
    u=abs(a[i].y-a[j].y)*abs(a[i].y-a[j].y);
    z=sqrt(v+u);
    return z;
}
void parpare()
{
    for(int i=1; i<=n; i++)
        for(int j=1; j<=n; j++)
            if(i==j)
                map[i][j]=0;
            else
                map[i][j]=map[j][i]=can(i,j);
}
void prim()
{
    for(int i=1; i<=n; i++)
        dist[i]=map[1][i],vis[i]=0,first[i]=1;//初始化,到达每个点的最短路径的起点都是1;
    vis[1]=1;
    int t=1;
    for(int i=2; i<=n; i++)
    {
        double minn=inf;
        int k;
        for(int j=1; j<=n; j++)
            if(!vis[j]&&dist[j]<minn)
                minn=dist[j],k=j;
        vis[k]=1;
        sum+=minn;
        if(minn!=0)//如果这条路径不是已经搭建过的 就输出起点和终点
            cout<<first[k]<<" "<<k<<endl;
        for(int j=1; j<=n; j++)
            if(!vis[j]&&dist[j]>map[k][j])
            {
                dist[j]=map[k][j];
                first[j]=k;//更新到达 j 点的的最短路径的起点
            }
    }
}
int main()
{
    cin>>n;
    for(int i=1; i<=n; i++)
        cin>>a[i].x>>a[i].y;
    parpare();
    int m;
    cin>>m;
    for(int i=1; i<=m; i++)
    {
        int u,v;
        cin>>u>>v;
        map[u][v]=map[v][u]=0;//搭建过的路径标记一下
    }
    sum=0;
    prim();
    return 0;
}

下一题

Arctic Network
The Department of National Defence (DND) wishes to connect several northern outposts by a wireless network. Two different communication technologies are to be used in establishing the network: every outpost will have a radio transceiver and some outposts will in addition have a satellite channel.
Any two outposts with a satellite channel can communicate via the satellite, regardless of their location. Otherwise, two outposts can communicate by radio only if the distance between them does not exceed D, which depends of the power of the transceivers. Higher power yields higher D but costs more. Due to purchasing and maintenance considerations, the transceivers at the outposts must be identical; that is, the value of D is the same for every pair of outposts.

Your job is to determine the minimum D required for the transceivers. There must be at least one communication path (direct or indirect) between every pair of outposts.
Input
The first line of input contains N, the number of test cases. The first line of each test case contains 1 <= S <= 100, the number of satellite channels, and S < P <= 500, the number of outposts. P lines follow, giving the (x,y) coordinates of each outpost in km (coordinates are integers between 0 and 10,000).
Output
For each case, output should consist of a single line giving the minimum D required to connect the network. Output should be specified to 2 decimal points.
Sample Input
1
2 4
0 100
0 300
0 600
150 750
Sample Output
212.13
感觉就是这一题 题意不是很好理解,天知道这一题我看了多久的题去理解题意;
题目大意:就是有 n 个点,我们要建立连接线使每个两个点之间都能相互联系,这 n 个点中又有 s 个点之间不用建立连接线就可以联系,让我们找到最小的 D 使得每个点之间都能相互联系;
大概思路:最小生成树+记录每条连接的边,找到第s-1大的点;

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int N=1e4+5,inf=0x3f3f3f3f;
double dist[N],map[N][N],dis[N];
int vis[N],n;
struct node
{
    int x,y;
} a[N];
double can(int i,int j)
{
    double xx,yy;
    xx=abs(a[i].x-a[j].x)*abs(a[i].x-a[j].x);
    yy=abs(a[i].y-a[j].y)*abs(a[i].y-a[j].y);
    return sqrt(xx+yy);
}
void prepare()
{
    for(int i=1; i<=n; i++)
        for(int j=1; j<=n; j++)
            if(i==j)
                map[i][j]=0;
            else
                map[i][j]=map[j][i]=can(i,j);
}
void prim()
{
    for(int i=1; i<=n; i++)
        dist[i]=map[1][i],vis[i]=0;
    vis[1]=1;
    for(int i=0; i<n-1; i++)
    {
        double minn=inf;
        int k;
        for(int j=1; j<=n; j++)
            if(!vis[j]&&dist[j]<minn)
                minn=dist[j],k=j;
        dis[i]=minn;
        vis[k]=1;
        for(int j=1; j<=n; j++)
            if(!vis[j]&&dist[j]>map[k][j])
                dist[j]=map[k][j];
    }
}
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int s;
        cin>>s>>n;
        for(int i=1; i<=n; i++)
            cin>>a[i].x>>a[i].y;
        prepare();
        prim();
        sort(dis,dis+n-1);
        printf("%.2f\n",dis[n-1-s]);
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值