soj1169: Networking_最小生成树

soj1169: Networking

http://acm.scu.edu.cn/soj/problem.action?id=1169

简介题意:求最小生成树的权值之和。prim和kruskal都可以,我都写了,不过kruskal数组开小了re了好几次,简直太愚蠢,大家要注意看题,本道题非常简单。

首先prim:

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define MAX 55
#define INF 0x3f3f3f3f
int map[MAX][MAX];
int dist[MAX];
bool visit[MAX];

void prim(int n)
{
    memset(dist,INF,sizeof(dist));
    memset(visit,0,sizeof(visit));
    for(int i = 1;i <= n; i++)
        if(map[1][i] != 0)
            dist[i] = map[1][i];
    visit[1] = 1;
    int price = 0;
    for(int i = 1;i <= n; i++)
    {
        int u;
        int min = INF;
        for(int j = 1;j <= n; j++)
            if(!visit[j] && dist[j]<min )
            {
                min = dist[j];
                u = j;
            }
        if(min < INF)
        {
            visit[u] = 1;
            price += min;
            for(int j = 1;j <= n; j++)
                if(!visit[j] && map[u][j]!=0 && dist[j]>map[u][j])
                    dist[j] = map[u][j];
        }
        else break;

    }
    printf("%d\n",price);
}

int main()
{
    int n,m;
    while(~scanf("%d",&n)&&n)
    {
        scanf("%d",&m);
        memset(map,0,sizeof(map));
        for(int i = 1;i <= m; i++)
        {
            int a,b,c;
            scanf("%d%d%d",&a,&b,&c);
            if(map[a][b] == 0)
                map[a][b] = map[b][a] = c;
            else if(map[a][b] > c)
                map[a][b] = map[b][a] = c;
        }
        prim(n);
    }
    return 0;
}

没什么好解释的,不过又排了一次第一,高兴~

然后接下来kruskal:

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define MAX 110
#define INF 0x3f3f3f3f
int pre[MAX];
int map[MAX][MAX];
int visit[MAX][MAX];

struct Node{
    int x,y,len;
}edge[MAX];

bool cmp(Node a, Node b)
{
    return a.len < b.len;
}

int find(int a)
{
    if(pre[a] == a)
        return a;
    else
        return pre[a] = find(pre[a]);
}

void Kruskal(int n,int k)
{
    for(int i = 0;i <= n; i++)
        pre[i] = i;
    int price = 0;
    for(int i = 1;i <= k; i++)
    {
        int a = find(edge[i].x);
        int b = find(edge[i].y);
        if(a != b)
        {
            pre[a] = b;
            price += edge[i].len;
        }
    }
    printf("%d\n",price);
}

int main()
{
    int n,m;
    while(~scanf("%d",&n)&&n)
    {
        scanf("%d",&m);
        memset(map,0,sizeof(map));
        memset(visit,0,sizeof(visit));
        for(int i = 1;i <=m ; i++)
        {
            int a,b,c;
            scanf("%d%d%d",&a,&b,&c);
            if(map[a][b] == 0)
                map[a][b] = map[b][a] = c;
            else if(map[a][b] > c)
                map[a][b] = map[b][a] = c;
        }
        int k = 1;
        for(int i = 1;i <= n; i++)
        for(int j = 1;j <= n; j++)
        {
            if(!visit[i][j] && map[i][j] != 0)
            {
                edge[k].x = i;
                edge[k].y = j;
                edge[k++].len = map[i][j];
                visit[i][j] = visit[j][i] = 1;
            }
        }
        sort(edge+1,edge+k,cmp);
        Kruskal(n,k-1);
    }
    return 0;
}

kruskal主要看数组啊!!!我刚才没有改MAX,所以re好多次,因为kruskal写的时候要注意本题可以两点之间很多条路线,所以记录最小的即可。要注意哦。

判断用哪一种方法,你就看点多不多,多的话你就用kruskal,少的话就prim

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
详细设计: 1. 框图 ``` +----------------+ +------------------------+ | | | | | 用户操作界面 |<--------->| 服务器处理 | | | | | +----------------+ +------------------------+ ``` 2. 程序实现 (1)添加学生信息 ``` void add_student_info(char* file_name, char* student_id, char* student_name, float student_score) { FILE* fp = fopen(file_name, "a"); fprintf(fp, "%s\t%s\t%.2f\n", student_id, student_name, student_score); fclose(fp); } ``` (2)修改学生信息 ``` void modify_student_info(char* file_name, char* student_id, char* student_name, float student_score) { FILE* fp = fopen(file_name, "r"); FILE* tmp_fp = fopen("tmp.txt", "w"); char buf[1024]; int found = 0; while (fgets(buf, sizeof(buf), fp) != NULL) { char id[10], name[20]; float score; sscanf(buf, "%s\t%s\t%f", id, name, &score); if (strcmp(id, student_id) == 0) { fprintf(tmp_fp, "%s\t%s\t%.2f\n", student_id, student_name, student_score); found = 1; } else { fprintf(tmp_fp, "%s", buf); } } fclose(fp); fclose(tmp_fp); if (found) { remove(file_name); rename("tmp.txt", file_name); } else { remove("tmp.txt"); } } ``` (3)删除学生信息 ``` void delete_student_info(char* file_name, char* student_id) { FILE* fp = fopen(file_name, "r"); FILE* tmp_fp = fopen("tmp.txt", "w"); char buf[1024]; int found = 0; while (fgets(buf, sizeof(buf), fp) != NULL) { char id[10]; sscanf(buf, "%s", id); if (strcmp(id, student_id) == 0) { found = 1; } else { fprintf(tmp_fp, "%s", buf); } } fclose(fp); fclose(tmp_fp); if (found) { remove(file_name); rename("tmp.txt", file_name); } else { remove("tmp.txt"); } } ``` (4)查询学生信息 ``` void query_student_info(char* file_name, char* student_id) { FILE* fp = fopen(file_name, "r"); char buf[1024]; int found = 0; while (fgets(buf, sizeof(buf), fp) != NULL) { char id[10], name[20]; float score; sscanf(buf, "%s\t%s\t%f", id, name, &score); if (strcmp(id, student_id) == 0) { printf("%s\t%s\t%.2f\n", id, name, score); found = 1; break; } } fclose(fp); if (!found) { printf("Student info not found!\n"); } } ``` (5)显示所有学生信息 ``` void display_all_student_info(char* file_name) { FILE* fp = fopen(file_name, "r"); char buf[1024]; while (fgets(buf, sizeof(buf), fp) != NULL) { char id[10], name[20]; float score; sscanf(buf, "%s\t%s\t%f", id, name, &score); printf("%s\t%s\t%.2f\n", id, name, score); } fclose(fp); } ``` 3. 核心步骤图 (1)添加学生信息 ![add_student_info](https://i.imgur.com/0xZ8JYf.png) (2)修改学生信息 ![modify_student_info](https://i.imgur.com/8fO8mY0.png) (3)删除学生信息 ![delete_student_info](https://i.imgur.com/FXiw3xq.png) (4)查询学生信息 ![query_student_info](https://i.imgur.com/1RUK2gX.png) (5)显示所有学生信息 ![display_all_student_info](https://i.imgur.com/SOJ8LhL.png)

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值