Semana de Pensamento em Programação6 Tarefa C - Dominando a Magia No Toto I

Título

Dongdong está entediado em sua cidade natal e quer cultivar. Existem n blocos de terras agrícolas, numerados de 1 a n. A agricultura
é uma obrigação.É sabido que Dongdong é um mágico.Ele pode consumir uma certa quantidade de MP para lançar magia em um campo, fazendo com que a água do Rio Amarelo suba ao céu. Ele também pode consumir uma certa quantidade de MP para construir um portal nos canais de dois campos, de modo que este campo se refira à água desse campo (1 <= n <= 3e2).
O consumo do céu do rio Amarelo é Wi, ei é o número da terra (1 <= Wi <= 1e5).
O custo de construção de um portal é Pij, iej são números de terras agrícolas (1 <= Pij <= 1e5, Pij = Pji, Pii = 0).
Dongdong é o consumo mínimo de todos os campos.

Entrada

Linha 1: um número n,
linha 2 para a linha n + 1: linha wi,
linha n + 2 para a linha 2n + 1: matriz, ou seja, pij

Resultado

Valor mínimo de MP de Dong Dong

Entrada de amostra

4
5	
4
4
3
0 2 2 2
2 0 3 3
2 3 0 4
2 3 4 0

Saída de amostra

9	

Idéias

O problema pode ser visto como um gráfico ponderado não direcionado, baseado apenas no estabelecimento de um portal, com um valor de peso do MP que estabelece o portal entre as duas terras agrícolas. Para lidar com o céu do rio Amarelo, outro pedaço de terra 0 pode ser adicionado para conectar a terra a todas as outras terras, e o peso do lado é o PM do céu do rio amarelo.
Dessa forma, o problema passa a ser a localização da árvore de abrangência mínima para gráficos ponderados não direcionados.Você pode usar prim ou kruskal para encontrar a árvore de abrangência mínima.

  • prim: um algoritmo ganancioso baseado em pontos. A idéia principal é manter um conjunto de pontos conectados. De cada ponto que não está no conjunto de pontos, um ponto com o menor custo para conectar o conjunto de pontos é selecionado e adicionado ao conjunto de pontos.
  • kruskal: toda vez que você tenta, com avidez, marcar a menor borda que não seja de árvore no gráfico como uma borda de árvore e ignorá-la ilegalmente.

Esta pergunta usa kruskal. Use e verifique se os dois pontos estão conectados.
Todas as arestas são classificadas de acordo com o valor do peso, de pequeno a grande;
considere cada aresta em ordem (a ordem dos pesos das arestas, de pequena a grande), desde que essa aresta não forme um círculo com a aresta que selecionamos, mantenha-a. Abandone esta aresta: após
selecionar com êxito (n-1) arestas, uma árvore de abrangência mínima é formada.Claro, se o algoritmo não puder selecionar (n-1) arestas, isso significa que o gráfico original não está conectado.

Código

#include <cstdio>
#include <algorithm>
using namespace std;
int n,edges=0;
int field[305][305];
int father[300];
struct edge{
    int u,v,w;
    bool operator<(edge e)const{
        return w<e.w;
    }
}e[300*300+5];

int find(int x){
    if(father[x]==x)
        return x;
    return father[x]=find(father[x]);
}

bool unit(int x,int y){
    x=find(x);y=find(y);
    if(x==y)
        return false;
    father[y]=x;
    return true;
}

int kruskal(){
    sort(e,e+edges);
    int ans=0,cnt=0;
    for(int i=0;i<edges;i++){
        if(unit(e[i].u, e[i].v)){
            ans+=e[i].w;
            cnt++;
            if(cnt==n)
                break;
        }
    }
    return ans;
}

int main() {
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&field[0][i]);
    }
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            scanf("%d",&field[i][j]);
    for(int i=0;i<=n;i++){
        for(int j=i+1;j<=n;j++){
            e[edges].u=i;
            e[edges].v=j;
            e[edges].w=field[i][j];
            edges++;
        }
    }
    for(int i=0;i<=n;i++)
        father[i]=i;
    int ans=kruskal();
    printf("%d",ans);
    return 0;
}

Link do título

Publicado 24 artigos originais · elogiado 2 · visitas 435

Acho que você gosta

Origin blog.csdn.net/weixin_43805228/article/details/105184535
Recomendado
Clasificación