2020.05.17最短路&最小生成树总结

这次作业做的题量有点少,主要是感觉这部分题有点难,写起来很费劲,所以就只做了四个题,下周得更努力一点才行。
Restoring Road Network
Problem StatementIn Takahashi Kingdom, which once existed, there are NNcities, and some pairs of cities are connected bidirectionally by roads. The following are known about the road network:People traveled between cities only through roads. It was possible to reach any city from any other city, via intermediate cities if necessary.Different roads may have had different lengths, but all the lengths were positive integers.Snuke the archeologist found a table with NN rows and NNcolumns, AA, in the ruin of Takahashi Kingdom. He thought that it represented the shortest distances between the cities along the roads in the kingdom.Determine whether there exists a road network such that for each uu and vv, the integer Au,vAu,v at the uu-th row and vv-th column of AA is equal to the length of the shortest path from City uu to City vv. If such a network exist, find the shortest possible total length of the roads.Constraints1≤N≤3001≤N≤300If i≠ji≠j, 1≤Ai,j=Aj,i≤1091≤Ai,j=Aj,i≤109.Ai,i=0Ai,i=0InputsInput is given from Standard Input in the following format:NN
A1,1A1,1 A1,2A1,2 … A1,NA1,N
A2,1A2,1 A2,2A2,2 … A2,NA2,N

AN,1AN,1 AN,2AN,2 … AN,NAN,N
OutputsIf there exists no network that satisfies the condition, print -1. If it exists, print the shortest possible total length of the roads.Sample Input 13
0 1 3
1 0 2
3 2 0
Sample Output 13
The network below satisfies the condition:City 11 and City 22 is connected by a road of length 11.City 22 and City 33 is connected by a road of length 22.City 33 and City 11 is not connected by a road.Sample Input 23
0 1 3
1 0 1
3 1 0
Sample Output 2-1
As there is a path of length 11 from City 11 to City 22 and City 22to City 33, there is a path of length 22 from City 11 to City 33. However, according to the table, the shortest distance between City 11 and City 33 must be 33.Thus, we conclude that there exists no network that satisfies the condition.Sample Input 35
0 21 18 11 28
21 0 13 10 26
18 13 0 23 13
11 10 23 0 17
28 26 13 17 0
Sample Output 382
Sample Input 43
0 1000000000 1000000000
1000000000 0 1000000000
1000000000 1000000000 0
Sample Output 43000000000
这个题是一共有N个城市,通过N-1条边连接。
现在给出一个N x N的矩阵,表示从i->j的最短路径,求能否根据这个N x N的矩阵求出最短路,如果最短路出错,输出-1
本题是最短路的题,如果存在i->k + k->j的最短路径和< i->j的最短距离,那么这个矩阵是错的,即输出-1。如果存在i->2*k->j的最短路径和= i->j的最短距离,那么i->j的这条边是不需要存在的(走同样的路程,能通过更多的点(k点),所以选择i->k->j而不是i->j)下面上代码

#include<iostream>
#include<cstdio>
#include<iostream>
using namespace std;
typedef long long LL;
LL A[305][305];
int main()
{
    ios::sync_with_stdio(0);
    int n;
    cin>>n;
    for(int i=0; i<n; i++)
    {
        for(int j=0; j<n; j++)
        {
            cin>>A[i][j];
        }
    }
    LL ans=0;
    for(int i=0; i<n; i++)
    {
        for(int j=0; j<i+1; j++)
        {
            bool flag=true;
            for(int k=0; k<n; k++)
            {
                if(A[i][j]>A[i][k]+A[k][j])
                {
                    cout<<"-1"<<endl;
                    return 0;
                }
                else if(i!=k&&j!=k&&A[i][j]==A[i][k]+A[k][j])
                    flag=false;
            }
            if(flag)
            {
                ans+=A[i][j];
            }
        }
    }
    cout<<ans<<endl;
    return 0;
}

Eddy’s picture
Eddy begins to like painting pictures recently ,he is sure of himself to become a painter.Every day Eddy draws pictures in his small room, and he usually puts out his newest pictures to let his friends appreciate. but the result it can be imagined, the friends are not interested in his picture.Eddy feels very puzzled,in order to change all friends 's view to his technical of painting pictures ,so Eddy creates a problem for the his friends of you.
Problem descriptions as follows: Given you some coordinates pionts on a drawing paper, every point links with the ink with the straight line, causes all points finally to link in the same place. How many distants does your duty discover the shortest length which the ink draws?
InputThe first line contains 0 < n <= 100, the number of point. For each point, a line follows; each following line contains two real numbers indicating the (x,y) coordinates of the point.

Input contains multiple test cases. Process to the end of file.
OutputYour program prints a single real number to two decimal places: the minimum total length of ink lines that can connect all the points.
Sample Input3
1.0 1.0
2.0 2.0
2.0 4.0
Sample Output3.41
本题直接上代码

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<string>
#include<algorithm>
#define INF 0x3f3f3f3f
typedef struct nn
{
    double x,y,d;
} Node;
double Map[105][105],sum,FN=INF;
int s[105],n;
Node node[105];
void init()
{
    for(int i=1; i<=n; i++)
    {
        for(int j=i+1; j<=n; j++)
            Map[j][i]=Map[i][j]=sqrt(pow(node[i].x-node[j].x,2)+pow(node[i].y-node[j].y,2));
        node[i].d=FN;
        s[i]=0;
    }
}
void solve()
{
    double Min;
    int m;
    s[1]=1;
    sum=0;
    m=1;
    for(int k=2; k<=n; k++)
    {
        for(int i=1; i<=n; i++)
            if(s[i]==0&&node[i].d>Map[m][i])
                node[i].d=Map[m][i];
        Min=FN;
        for(int j=1; j<=n; j++)
            if(s[j]==0&&Min>node[j].d)
            {
                m=j;
                Min=node[j].d;
            }
        s[m]=1;
        sum+=Min;
    }
}
int main()
{
    while(~scanf("%d",&n))
    {
        for(int i=1; i<=n; i++)
            scanf("%lf%lf",&node[i].x,&node[i].y);
        init();
        solve();
        printf("%.2lf\n",sum);
    }
}

齐头并进
在一个叫奥斯汀的城市,有n个小镇(从1到n编号),这些小镇通过m条双向火车铁轨相连。当然某些小镇之间也有公路相连。为了保证每两个小镇之间的人可以方便的相互访问,市长就在那些没有铁轨直接相连的小镇之间建造了公路。在两个直接通过公路或者铁路相连的小镇之间移动,要花费一个小时的时间。现在有一辆火车和一辆汽车同时从小镇1出发。他们都要前往小镇n,但是他们中途不能同时停在同一个小镇(但是可以同时停在小镇n)。火车只能走铁路,汽车只能走公路。现在请来为火车和汽车分别设计一条线路;所有的公路或者铁路可以被多次使用。使得火车和汽车尽可能快的到达小镇n。即要求他们中最后到达小镇n的时间要最短。输出这个最短时间。(最后火车和汽车可以同时到达小镇n,也可以先后到达。)样例解释:在样例中,火车可以按照 1⟶3⟶41⟶3⟶4 行驶,汽车 1⟶2⟶41⟶2⟶4 按照行驶,经过2小时后他们同时到过小镇4。Input单组测试数据。 第一行有两个整数n 和 m (2≤n≤400, 0≤m≤n*(n-1)/2) ,表示小镇的数目和铁轨的数目。 接下来m行,每行有两个整数u 和 v,表示u和v之间有一条铁路。(1≤u,v≤n, u≠v)。 输入中保证两个小镇之间最多有一条铁路直接相连。Output输出一个整数,表示答案,如果没有合法的路线规划,输出-1。Sample Input4 2
1 3
3 4Sample Output2
本题题意就是两个最短路中找最大的那一个。此题不一定有解,所以一开始保存当前节点的应该初始化为第一个点,因为有火车就没有公路,也无法到达终点·。所以两次搜索求最短路,然后输出最大的那个即可

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 500;
const int INF = 0x3f3f3f3f;
int a[N][N],dis[N];
bool vis[N];
void solve(int n)
{
    for(int i=1; i<=n; i++)
    {
        if(i == 1)
        {
            vis[i] = 1;
            dis[i] = INF;
        }
        else
        {
            if(a[1][i] == 1)
                dis[i] = a[1][i];
            else
                dis[i] = INF;
        }
    }
    for(int i=2; i<=n; i++)
    {
        int Min = INF, ans = 1;
        for(int j=1; j<=n; j++)
        {
            if(!vis[j] && dis[j] < Min)
            {
                Min = dis[j];
                ans = j;
            }
        }
        if(ans == -1)
        {
            break;
        }
        vis[ans] = 1;
        dis[ans] = Min;
        for(int k=1; k<=n; k++)
        {
            if(vis[k])
                continue;
            if(a[ans][k]>0 && Min+a[ans][k] < dis[k])
            {
                dis[k] = Min+a[ans][k];
            }
        }
    }
}
int main()
{
    int n, m;
    cin >> n >> m;
    memset(a, 0, sizeof(a));
    memset(vis, 0, sizeof(vis));
    int x, y;
    for(int i=1; i<=m; i++)
    {
        cin >> x >> y;
        a[x][y] = a[y][x] = 1;
    }
    if(a[1][n] == 1)
    {
        for(int i=1; i<=n; i++)
        {
            for(int j=1; j<=n; j++)
            {
                if(i == j)
                    a[i][j] = 0;
                else if(a[i][j] == 0)
                    a[i][j] = 1;
                else
                    a[i][j] = 0;
            }
        }
    }
    solve(n);
    if(dis[n] == INF)
        cout << "-1" << endl;
    else
        cout << dis[n] << endl;
    return 0;
}
原创文章 25 获赞 38 访问量 833

猜你喜欢

转载自blog.csdn.net/weixin_46434074/article/details/106172527