zoukankan      html  css  js  c++  java
  • Dungeons and Candies

    Zepto Code Rush 2014:http://codeforces.com/problemset/problem/436/C

    题意:k个点,每个点都是一个n * m的char型矩阵。对与每个点,权值为n * m或者找到一个之前的点,取两个矩阵对应位置不同的字符个数乘以w。找到一个序列,使得所有点的权值和最小。

    题解:很明显的最小生成树。但是要加入一个0点,边权为n*m,其余k个点两两建立一条边,边权是diff[i][j]*w,最后这一题,我要死掉的地方就是输出,不仅要输出费用,还要输出边,但是这里的边,看了半天,才知道,要按dfs序列输出,并且第一个点的前一个点必须是0.哎,这一题,只能说明自己太渣了。有点伤心。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 using namespace std;
     6 int n,m,k,w,num,cost,ct;
     7 int fa[1002];
     8 int g[1002][1002];
     9 void init(){
    10    for(int i=0;i<=k;i++)
    11       fa[i]=i;
    12 }
    13 int  Find(int x){
    14     int s;
    15     for(s=x;s!=fa[s];s=fa[s]);
    16     while(s!=x){
    17         int temp=fa[x];
    18         fa[x]=s;
    19         x=temp;
    20     }
    21    return s;
    22 }
    23 struct Node{
    24   int x;
    25   int y;
    26   int val;
    27 }edge[1000002];
    28 int cmp1(Node a,Node b){
    29   return a.val<b.val;
    30 }
    31 int cmp2(Node a,Node b){
    32    return a.y<b.y;
    33 }
    34 char mp[1002][12][12];
    35 void deal(){
    36    for(int i=1;i<=k;i++){
    37       for(int j=i+1;j<=k;j++){
    38         int counts=0;
    39         for(int g=1;g<=n;g++){
    40             for(int h=1;h<=m;h++){
    41                 if(mp[i][g][h]!=mp[j][g][h])
    42                     counts++;
    43             }
    44         }
    45         edge[++num].x=i;
    46         edge[num].y=j;
    47         edge[num].val=counts*w;
    48       }
    49    }
    50    for(int i=1;i<=k;i++){
    51      edge[++num].x=0;
    52      edge[num].y=i;
    53      edge[num].val=n*m;
    54    }
    55 }
    56 void print(int u,int fa){
    57      for(int i=0;i<=k;i++){
    58         if(g[u][i]>=0&&i!=fa){
    59             printf("%d %d
    ",i,u);
    60              print(i,u);
    61         }
    62      }
    63 
    64 
    65 }
    66 int main(){
    67     while(~scanf("%d%d%d%d",&n,&m,&k,&w)){
    68         init();
    69         memset(g,-1,sizeof(g));
    70         for(int i=1;i<=k;i++){
    71             for(int j=1;j<=n;j++){
    72                 for(int h=1;h<=m;h++)
    73                     cin>>mp[i][j][h];
    74             }
    75         }
    76         num=0;
    77         deal();
    78         sort(edge+1,edge+num+1,cmp1);
    79         ct=0;cost=0;
    80         for(int i=1;i<=num;i++){
    81             int x=Find(edge[i].x);
    82             int y=Find(edge[i].y);
    83             if(x!=y){
    84                 fa[x]=y;
    85                 int tx=edge[i].y;
    86                 int ty=edge[i].x;
    87                  g[tx][ty]=g[ty][tx]=edge[i].val;
    88                  ct++;
    89                    cost+=edge[i].val;
    90             }
    91             if(ct==k)break;
    92         }
    93            printf("%d
    ",cost);
    94                 print(0,0);
    95     }
    96 }
    View Code
  • 相关阅读:
    课后作业之评价
    课堂作业之寻找水王
    构建之法阅读笔记04
    课下作业
    构建之法阅读笔记03
    学习进度条九
    学习进度条八
    冲刺第五天
    构建之法阅读笔记02
    冲刺第四天
  • 原文地址:https://www.cnblogs.com/chujian123/p/3876402.html
Copyright © 2011-2022 走看看