1248762042 发表于 2021-11-14 22:00:23

修路问题

畅通工程
某省调查城镇交通状况,得到现有城镇道路统计表,表中列出了每条道路直接连通的城镇。省政府“畅通工程”的目标是使全省任何两个城镇间都可以实现交通(但不一定有直接的道路相连,只要互相间接通过道路可达即可)。问最少还需要建设多少条道路?

Input
测试输入包含若干测试用例。每个测试用例的第1行给出一个正整数和一个非负整数,分别是城镇数目N ( < 1000 )和道路数目M;随后的M行对应M条道路,每行给出一对正整数,分别是该条道路直接连通的两个城镇的编号。为简单起见,城镇从1到N编号。 注意:两个城市之间可以有多条道路相通,也就是说 3 3 1 2 1 2 2 1 这种输入也是合法的 当N为0时,输入结束,该用例不被处理。

Output
对每个测试用例,在1行里输出最少还需要建设的道路数目。

输入示例
4 2
1 3
4 3
3 3
1 2
1 3
2 3
5 2
1 2
3 5
999 0
0
输出示例
1
0
2
998

jhq999 发表于 2021-11-15 19:32:51

本帖最后由 jhq999 于 2021-11-15 19:34 编辑

输入示例和题目不符,N在哪?M在哪?才明白原来是4个示例

jhq999 发表于 2021-11-15 20:52:25

本帖最后由 jhq999 于 2021-11-15 22:01 编辑

#include<stdio.h>
#include<stdlib.h>

void roadoutput(int (*road),int m,int n)
{
        int i=0,j=0,count=0;
        for (i = 1; i <= n; i++)//找出没通路的
        {
                for (j = 0; j < m; j++)
                {
                        if (i==road||i==road)
                        {
                                break;;
                        }
                }
                if (j==m)
                {
                        count++;
                }
        }
        for (i = 0; i < m; i++)//把互通的找出来算成一个孤立的城镇
        {
                if (!road)
                {
                        road=1;
                        count++;

                        for (j = i+1; j < m; j++)
                        {
                                if (!road)
                                {
                                        if ((road==road)||(road==road)\
                                                ||(road==road)||(road==road))
                                        {
                                                road=1;
                                        }
                                }
                        }
                }
        }

        printf("%d\n",count-1);//孤立的城镇互通最少的路的条数是孤立的城镇数量-1
       

}

int main()
{

        int i=0,j=0,n=0,m=0;
        while (1)
        {
                scanf("%d",&n);
                if (!n)
                {
                        break;
                }
                scanf("%d",&m);
                int (*road)=(int(*))malloc(m*3*sizeof(int));
                for (i = 0; i <m; i++)
                {
                        scanf("%d %d",&road,&road);
                        road=0;
                        fflush(stdin);
                }
                roadoutput(road,m,n);
                free(road);

        }
        return 0;
}
10 4
1 2
3 4
5 6
9 10
5
10 6
1 2
1 3
2 3
4 5
8 9
9 10
4
4 2
1 3
4 3
1
3 3
1 2
1 3
2 3
0
5 2
1 2
3 5
2
999 0
998
0

learner-ray 发表于 2021-11-16 00:57:19

#include<stdio.h>

void RoadNum(void);        

int main(void)
{
        RoadNum();
       
        return 0;
}

void RoadNum(void)        //该函数用来实现修路问题,整体思想为n个城镇至少需要n-1条有效路径。m是现存的路径,需要判断里面是否有无效路径,比如同时存在1 2 2 1。
{
        int n, m;         // n为城镇数量,m 为现存路径。
        int count = 0; //用来统计m中的无效路径。
        int i, k;         //用来循环
        int j= 0;        //用来存储还需要几条路。
        int road; // 将还需要几条路存储在road数组中。
       
        printf("请输入城镇和道路信息:\n");
        while (1)
        {
                count = 0;        //辅助统计现有多少条路。
                scanf("%d", &n);
                if (n == 0) // 设置循环终止条件,输入0结束。
                {
                        break;
                }
                scanf("%d", &m);
               
                struct Exist       // 每一条路是两个城镇来表示,因此定义了一个结构体来表示。
                {
                        int t1;
                        int t2;
                };
               
                struct Exist exi;         // 现存m条路因此定义了一个exi的数组,来存放。
               
                for (i = 0; i < m; i++)                //输入城镇和道路信息;
                {
                        scanf("%d%d", &(exi.t1), &(exi.t2));
                        if (exi.t1 > n || exi.t2 > n) //假如5个城镇的话,用1,2,3,4,5来表示,输入的数字不能超过5,否则报错。
                        {
                                printf("输入错误\n");
                                return;
                        }
                }
               
                for (i = 0; i < m; i++) // 无效路径的判断。
                {
                        for (k = i+1; k < m; k++)
                        {
                                if ((exi.t1 == exi.t1 && exi.t2 == exi.t2) || (exi.t1 = exi.t2 && exi.t2 == exi.t1))
                                {
                                        count++;
                                        break; //非常重要,防止重复计数。
                                }
                        }
                }
               
                road = (n-1) - (m-count);         // n-1为需要的路径,m-count为现有的有效路径。
        }
       
        printf("输出结果\n");
       
        for (i = 0; i < j; i++)
        {
                printf("%d\n", road);
        }
       
        return;
}
结果显示:
请输入城镇和道路信息:
4 2
1 3
4 3
3 3
1 2
1 3
2 3
5 2
1 2
3 5
999 0
0
输出结果
1
0
2
998

--------------------------------
Process exited after 11.71 seconds with return value 0
请按任意键继续. . .

1248762042 发表于 2021-11-16 12:22:39

#include <iostream>

using namespace std;

typedef struct ufset *UFset;
typedef struct ufset
{
        int *parent;
        int *root;
}UFS;

UFset UFinit(int size)
{
        UFset U = new ufset;
        U->parent = new int;
        U->root = new int;
        for (int e = 1; e <= size; e++)
        {
                U->parent = 1;
                U->root = 1;
        }
        return U;
}

int UFfind(int e, UFset U)
{
        int i, j = e;
        while ( !U->root )
        {
                j = U->parent;
        }
        while ( j != e )
        {
                i = U->parent;
                U->parent = j;
                e = i;
        }
        return j;
}

int UFunion(int i, int j, UFset U)
{
        if (i == j) return i;
        if (U->parent < U->parent)
        {
                U->parent += U->parent;
                U->root = 0;
                U->parent = j;
                return j;
        }
        else {
                U->parent += U->parent;
                U->root = 0;
                U->parent = i;
                return i;
        }
}

void UFfree(UFset U)
{
        delete [] U->parent;
        delete [] U->root;
        delete U;
}

void uni(int x, int y, UFset uf)
{
        int a = UFfind(x, uf),
                b = UFfind(y, uf);
        UFunion(a, b, uf);
}

int main()
{
        int N, M, index1, index2, count;
       
        UFset uf;
       
        while (true)
        {
                count = 0;
                cin >> N;
                if ( N == 0 ) break;
                cin >> M;
               
                uf = UFinit(N);
               
                for (int i = 0; i < M; i++)
                {
                        cin >> index1 >> index2;
                        uni(index1, index2, uf);
                }
                for (int i = 1; i <= N; i++)
                {
                        int j = UFfind(i, uf);
                        if ( i == j ) count++;
                }
                cout << count - 1 << endl;
               
                UFfree(uf);
        }
}

1248762042 发表于 2021-11-16 12:23:37

1248762042 发表于 2021-11-16 12:22


我自己写出来了
页: [1]
查看完整版本: 修路问题