【数据结构与算法实习】题目6 旅行商(TSP)

题目描述:
hrek是一个大山里的邮递员,每天负责给所在地区的n个村庄派发信件。但杯具的是,由于道路狭窄,年久失修,村庄间的道路都只能单向通过,甚至有些村庄无法从任意一个村庄到达。这样我们只能希望尽可能多的村庄可以收到投递的信件。
Shrek希望知道如何选定一个村庄A作为起点(我们将他空投到该村庄),依次经过尽可能多的村庄,路途中的每个村庄都经过仅一次,最终到达终点村庄B,完成整个送信过程。这个任务交给你来完成。

输入格式:
第一行包括两个整数n,m,分别表示村庄的个数以及可以通行的道路的数目。
以下共m行,每行用两个整数v1和v2表示一条道路,两个整数分别为道路连接的村庄号,道路的方向为从v1至v2,n个村庄编号为[1, n]。

要求:
1 ≤ n ≤ 1,000,000
0 ≤ m ≤ 1,000,000
输入保证道路之间没有形成环

输出格式:
输出一个数字,表示符合条件的最长道路经过的村庄数。

输入样例:

4 3
1 4
2 4
4 3

输出样例:

3

题解:

//本题的逻辑结构:图
//本题的存储结构:顺序
//解题思路和算法:初始化有向图,按照题给写入顶点和有向边,获取每个点的入度写入数组,深度优先遍历入度为0的点,设置全局变量maxNum,
//              深度遍历的深度最大值如果大于maxNum则赋给maxNum,始终保持maxNum为最大值,最后输出maxNum
//效率:时间复杂度O(n^2)、空间复杂度O(1):
//测试数据: (1)输入:4 3
//               1 4
//               2 4
//               4 3
//               输出:3 
        // (2)输入:6
                // 5
                // 1 2
                // 2 3
                // 2 4
                // 4 5
                // 2 6
                // 输出:4

#include<stdio.h>
#include<malloc.h>
#define MaxVertexNum 100
#define INFINITY 0
#define max(a,b) ((a)>(b)?(a):(b))
typedef int Vertex;
typedef int DataType;

typedef struct GNode * PtrToGNode;
struct GNode
{
    /* data */
    int Nv;
    int Ne;
    DataType G[MaxVertexNum][MaxVertexNum];
};
typedef PtrToGNode MGraph;

typedef struct ENode * PtrToENode;
struct ENode
{
    /* data */
    Vertex V1, V2;
};
typedef PtrToENode Edge;

MGraph CreateGraph(int VertexNum){
    Vertex V, W;
    MGraph Graph;

    Graph = (MGraph) malloc (sizeof(struct GNode));
    Graph->Nv = VertexNum;
    Graph->Ne = 0;

    for(V = 0; V < Graph->Nv; V++){
        for(W = 0; W < Graph->Nv; W++){
            Graph->G[V][W] = INFINITY;
        }
    }
    return Graph;
}

void InsertEdge(MGraph Graph, Edge E){
    Graph->G[E->V1-1][E->V2-1] = 1;
}

MGraph BuildGraph(){
    MGraph Graph;
    Edge E;
    Vertex V;
    int Nv, i;

    scanf("%d", &Nv);
    Graph = CreateGraph(Nv);

    scanf("%d", &(Graph->Ne));
    if(Graph->Ne!=0){
        E = (Edge)malloc(sizeof(struct ENode));
        for(i = 0; i<Graph->Ne; i++){
            scanf("%d %d", &E->V1, &E->V2);
            InsertEdge(Graph, E);
        }
    }
    return Graph;
}

int maxNum=0;

int findN(MGraph G1, int x, int num){
    int count = 0;
    for(int i=0;i<G1->Nv;i++){
        if(G1->G[x][i]){
            num = findN(G1, i, ++num);
            count++;
        }
    }
    if(!count){
        maxNum = max(maxNum, num);
        num--;
    }
    return num;
}


int main(){
    MGraph G1 = BuildGraph();
    // for(int i = 0; i<G1->Nv;i++){
    //     for(int j=0;j<G1->Nv;j++){
    //         printf("%d ", G1->G[i][j]);
    //     }
    //     printf("\n");
    // }

    int arr[G1->Nv];
    int find0 = 0;
    for(int i = 0; i<G1->Nv;i++){
        for(int j=0;j<G1->Nv;j++){
            find0 += G1->G[j][i];
        }
        arr[i] = find0;
        if(arr[i]==0){
            findN(G1, 0, 0);
        }
        find0 = 0;
    }
    printf("%d", maxNum+1);

    return 0;
}

// 6
// 5
// 1 2
// 2 3
// 2 4
// 4 5
// 2 6

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

a9c93f2300

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值