1393: Enlace (enlace)

1393:
Límite de tiempo de enlace: 1000 ms Límite de memoria: 65536 KB
[Descripción del título]
Tyvj tiene un año y el sitio web ha aumentado de unos pocos usuarios iniciales a decenas de miles de usuarios. Con el crecimiento gradual del sitio web de Tyvj, The el número de administradores también está aumentando. Ahora que usted es el oficial de enlace de la administración de Tyvj, espero que pueda encontrar algunos canales de comunicación para que los administradores puedan comunicarse entre sí (ya sea directa o indirectamente). Tyvj es un sitio web de bienestar público sin demasiadas ganancias, por lo que debe mantener el costo lo más bajo posible.
Como ya sabe, los canales de comunicación de Tyvj se dividen en dos categorías, una son los canales de comunicación obligatorios, sin importar el precio, debe elegirlos todos; la otra son los canales de comunicación opcionales, puede elegir entre Elegir algunos canales de comunicación que servirán como contactos finales del administrador. El canal de acceso que otorga la garantía de datos permite que todos los administradores se comuniquen.
[Entrada]
La primera línea n, m significa que Tyvj tiene un total de n administradores y m canales de comunicación; la
segunda línea a m+1 línea, cada línea tiene cuatro números enteros no negativos, p, u, v, w cuando p Cuando =1, significa que este canal de comunicación es un canal de comunicación obligatorio; cuando p=2, significa que este canal de comunicación es un canal de comunicación opcional; u, v, w significa que esta información describe la comunicación entre los administradores u y v canal, u puede recibir información de v, y v también puede recibir información de u, y w representa la tarifa.
[Salida]
El costo mínimo de comunicación.
[Ejemplo de entrada]
5 6
1 1 2 1 1 2
3 1 1 3
4 1 1
4 1
1 2 2 5 10
2 2 5 5
[Ejemplo de salida]
9
[Preguntar]
[Ejemplo de explicación]
En 1-2-3-4-1, hay cuatro canales obligatorios que forman un anillo y pueden conectarse entre sí. Es necesario que todos los administradores se conecten, y es necesario conectar los administradores No. 2 y No. 5, y elegir un canal con un costo de 5, por lo que el costo total es de 9.
[Nota]
Puede haber múltiples canales de comunicación entre U y v, y su programa debe acumular todos los canales necesarios entre u y v [
Rango de datos]
Para el 30 % de los datos, n≤10, m≤100;
para el 50 % de los datos, n≤200, m≤1000
Para el 100% de los datos, n≤2000, m≤10000

#include <iostream>
#include <stdio.h>
#include <algorithm>
using namespace std;
const int maxn=2010;  // 最大点数
const int maxm=20010; // 最大边数
struct point{
    int x,y,c;  // 无向边(x,y),权值为c
}a[maxm];       // 存储询问的边
bool cmp(const point &a,const point &b){
    return a.c<b.c;
}
int n,m,ans,k;    // n为点数,m为边数(包括询问边),ans为最小生成树的边权和,k为询问边的数量。
int f[maxn];      // 并查集,用于判断两个节点是否在同一集合
int find(int x){   // 查找x所属集合的代表元
    if(f[x]==x) return x;
    return f[x]=find(f[x]);  // 路径压缩
}
void unionn(int x,int y){  // 将x和y所属集合合并
    int a=find(x);
    int b=find(y);
    if(a!=b) f[a]=b;
}
int main(){
    scanf("%d %d",&n,&m);
    for(int i=1;i<=n;i++) f[i]=i;  // 并查集初始化,每个节点的父亲为自己
    int p,u,v,w;
    for(int i=1;i<=m;i++){
        scanf("%d %d %d %d",&p,&u,&v,&w);
        if(p==1){  // 如果该边是连通操作,则将u和v所在的集合合并
            unionn(u,v);ans+=w;
        }
        else{     // 否则,将该边保存到a数组中,用于后续的Kruskal算法构造最小生成树
            k++;a[k].x=u;a[k].y=v;a[k].c=w;
        }
    }
    sort(a+1,a+k+1,cmp);  // 对询问边按照权重进行排序
    for(int i=1;i<=k;i++){
        if(find(a[i].x)!=find(a[i].y)){  // 如果a[i]的两个端点不在同一个集合中,则可以选择使用这条边,将它们合并,并增加对应的权值。
            unionn(a[i].x,a[i].y);
            ans+=a[i].c;
        }
    }
    printf("%d",ans);  // 输出最小生成树的权值和
    return 0;
}

Supongo que te gusta

Origin blog.csdn.net/lybc2019/article/details/128442558
Recomendado
Clasificación