POJ1789-Truck History .

题目链接:http://poj.org/problem?id=1789
题目的大概意思就是给你n个字符串。每个字符串只有7的长度。然后分别给这些字符串编号。不同编号之间的距离就是他们有多少个不同的字母。(同一个位置字母不相同也算)然后一个编号只能由另一个派生出来。派生的代价就是他们呢之间的距离。现在要你求最小的总代价。
编号的范围是2-2000.属于稠密图。求最小生成树最好用prim算法。用克鲁斯卡尔会可能会超时。

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=2220;
int G[N][N];
int low[N],vis[N];
char s[N][10];
int n;
int prim()
{
    memset(vis,0,sizeof(vis));
    int  pos=0;
    int min;
    int ans=0;
    vis[0]=1;
    for(int i=0;i<n;i++)
    low[i]=G[pos][i];
    for(int i=0;i<n-1;i++)
    {
        min=100;
        for(int j=0;j<n;j++)
        {
            if(!vis[j]&&low[j]<min)
            {
                min=low[j];
                pos=j;
            }
        }
        vis[pos]=1;
        ans+=min;
        for(int j=0;j<n;j++)
        {
            if(!vis[j]&&low[j]>G[pos][j])
            low[j]=G[pos][j];
        }
    }
    return ans;
}
int main()
{
    while(scanf("%d",&n)!=EOF&&n)
    {
        for(int i=0;i<n;i++)
        scanf("%s",s[i]);
        int cnt=0;
        for(int i=0;i<n;i++)
        {
            for(int j=i+1;j<n;j++)
            {
                int tmp=0;
                for(int k=0;k<7;k++)
                {
                if(s[i][k]!=s[j][k])
                    tmp++;
                }
                int u=i;
                int v=j;
              G[u][v]=tmp;
              G[v][u]=tmp;
            }
        }
    int ans=prim();
    printf("The highest possible quality is 1/%d.\n",ans);  
    }
    return 0;
}
posted @ 2016-04-26 22:08  __NaCl  阅读(118)  评论(0编辑  收藏  举报