最小生成树的建模+POJ - 1789Truck History

心不动则不痛 提交于 2020-03-02 10:43:05

Truck History
Description:
给定N个字符串,每个字符串都继承于另一个字符串(除了祖先字符串),某个字符串转为另一个字符串的花费为他们每一位不相同的字符数。 求最小花费Q。

字符串与字符串之间的关系正是点与点之间的关系,每一位不相同的字符数就是边权,最终每个点都要有父节点(树的连通性),不能多继承(无环性)。

在这里插入图片描述

注意:
不要用c++的cin输入流,和string,速度太慢了以至于TLE.

#include<stdio.h>
#include<iostream>
#include<cmath>
#include<math.h>
#include<string>
#include<string.h>
#include<algorithm>
#define ll long long
using namespace std;
const int maxn=2005;  //数组要开够
int n,m,fa[maxn];
char dots[2005][10];
struct Edge{
    int u,v,cost;
}t[maxn*maxn];

int get_cost(int x,int y){
    int sum=0;
    for(int i=0;i<7;i++){
        if(dots[x][i]!=dots[y][i]) sum++;
    }
    return sum;
}

bool cmp(Edge a,Edge b){
    return a.cost<b.cost;
}

int find(int x){
    return (x==fa[x])?x:fa[x]=find(fa[x]);
}
void merge(int x,int y){
    fa[find(x)]=find(y);
}

int main(){
    while(scanf("%d",&n)&& n){
        m = n*(n-1)/2;
        for(int i=1;i<=n;i++) scanf("%s",dots[i]);
        int cnt=1;
        for(int i=1;i<n;i++){
            for(int j=i+1;j<=n;j++){
                t[cnt].u=i;t[cnt].v=j;t[cnt].cost=get_cost(i,j);
                cnt++;
            }
        }
        for(int i=1;i<=n;i++) fa[i]=i;
        sort(t+1,t+m+1,cmp);
        int ans=0;
        for(int i=1;i<=m;i++){
            int u=t[i].u,v=t[i].v;
            if(find(u)!=find(v)){
                ans+=t[i].cost;
                merge(u,v);
            }
        }
        printf("The highest possible quality is 1/%d.\n",ans);
    }
    return 0;
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!