对于弱这种英语渣来说 这明明就是个英语阅读题啊!!……虽然已经习惯了。。不过这题寒假集训刚做过 在哪来一看还是没读懂……千刀万剐煮了我吧
一个字符串由7个小写字母组成 每个字符串表示一种状态 每个状态只能由另一种状态转换 转换耗时为两个字符串中不同字母的数量(即distance -> [0,7])
读出来这些就好办了 赤果果的最小生成树,Prim Kruskal都可以 测了测这题Kruskal耗时少……但2000个点的话1999000条边(无向) 排序应该也蛮久。。而且这种稠密图Prim应该会快点吧……纠结……
代码如下
Kruskal
#include
using namespace std;
typedef struct Edge
{
int u,v,w;
bool operator < (const struct Edge a)const
{
return w < a.w;
}
}Edge;
Edge eg[1999100];
char str[2333][8];
int pre[2333];
int tp;
void Init(int n)
{
int i;
for(i = 0; i < n; ++i)
pre[i] = i;
}
int Find(int x)
{
if(pre[x] != x) pre[x] = Find(pre[x]);
return pre[x];
}
int GetW(char *a,char *b)
{
int i,cnt = 0;
for(i = 0; i < 7; ++i)
{
if(a[i] != b[i]) cnt++;
}
return cnt;
}
int main()
{
int n,i,j,cnt,k,r,sum;
while(~scanf("%d",&n) && n)
{
Init(n);
tp = 0;
for(i = 0; i < n; ++i)
{
scanf("%s",str[i]);
for(j = 0; j < i; ++j)
{
eg[tp].u = j;
eg[tp].v = i;
eg[tp++].w = GetW(str[j],str[i]);
}
}
sort(eg,eg+tp);
cnt = sum = 0;
for(i = 0; i < tp; ++i)
{
k = Find(eg[i].u);
r = Find(eg[i].v);
if(k != r)
{
pre[k] = r;
cnt++;
sum += eg[i].w;
}
if(cnt == n-1) break;
}
printf("The highest possible quality is 1/%d.\n",sum);
}
return 0;
}
Prim
#include
using namespace std;
int mp[2000][2000],dis[2000],n;
bool vis[2000];
char str[2000][8];
int GetW(char *a,char *b)
{
int i,cnt = 0;
for(i = 0; i < 7; ++i)
{
if(a[i] != b[i]) cnt++;
}
return cnt;
}
int Prim()
{
memset(vis,0,sizeof(vis));
memset(dis,INF,sizeof(dis));
int i,p,m,j,sum = 0;
dis[0] = 0;
for(i = 0; i < n; ++i)
{
m = INF;
for(j = 0; j < n; ++j)
{
if(!vis[j] && dis[j] < m)
{
m = dis[j];
p = j;
}
}
vis[p] = 1;
sum += dis[p];
for(j = 0; j < n; ++j)
{
if(!vis[j] && dis[j] > mp[p][j])
{
dis[j] = mp[p][j];
}
}
}
return sum;
}
int main()
{
int i,j;
while(~scanf("%d",&n) && n)
{
for(i = 0; i < n; ++i)
{
scanf("%s",str[i]);
for(j = 0; j < i; ++j)
{
mp[i][j] = mp[j][i] = GetW(str[j],str[i]);
}
mp[i][j] = 0;
}
printf("The highest possible quality is 1/%d.\n",Prim());
}
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-11-03 21:31:36