博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Zepto Code Rush 2014——Dungeons and Candies
阅读量:6213 次
发布时间:2019-06-21

本文共 3715 字,大约阅读时间需要 12 分钟。

  • 题意:
    k个点,每一个点都是一个n * m的char型矩阵。对与每一个点,权值为n * m或者找到一个之前的点,取两个矩阵相应位置不同的字符个数乘以w。找到一个序列,使得全部点的权值和最小
  • 分析:
    首先,这个图是一个无向图。求权值和最小,每一个权值相应的是一条边,且每一个点仅仅能有一个权值即一条边,一个k个边,和生成树非常像,可是须要证明不能有环形。最好还是如果如今有三个点,每一个点的最小边成环,这时候是不能找到一个序列使得每一个点都取到它的最小边值的,所以,k个点k个边不能有环且边值和最小,就是最小生成树。
prim算法:
const int maxn = 1100;char ipt[maxn][11][11];int dist[maxn][maxn];int d[maxn], p[maxn];bool vis[maxn];int n, m, k, w;int main(){//    freopen("in.txt", "r", stdin);    while (~RIV(n, m, k, w))    {        CLR(dist, 0);        REP(i, k)        {            vis[i] = false;            d[i] = n * m;            p[i] = -1;        }        REP(i, k) REP(j, n)            RS(ipt[i][j]);        REP(i, k) REP(j, k) REP(ii, n) REP(jj, m)            dist[i][j] += (ipt[i][ii][jj] != ipt[j][ii][jj]) * w;        d[0] = 0;        int sum = n * m;        VI ans;        REP(i, k)        {            int M = INF, ind;            REP(j, k)                if (!vis[j] && d[j] < M)                {                    ind = j;                    M = d[j];                }            vis[ind] = true;            sum += M;            ans.push_back(ind);            REP(j, k)            {                if (!vis[j] && dist[ind][j] < d[j])                {                    d[j] = dist[ind][j];                    p[j] = ind;                }            }        }        WI(sum);        REP(i, ans.size())        {            cout << ans[i] + 1 << ' ' << p[ans[i]] + 1 << endl;        }    }    return 0;}
kruskal:
const int maxn = 1100;struct Edge{    int from, to, dist;    int operator< (const Edge& rhs) const    {        return dist < rhs.dist;    }    Edge (int from = 0, int to = 0, int dist = 0)    {        this->from = from;        this->to = to;        this->dist = dist;    }};vector
G[maxn];int in[maxn];vector
edges;int fa[maxn];char ipt[maxn][105];int diff[maxn][maxn];int n, m, k, w;int find(int n){ return (n == fa[n]) ? n : (fa[n] = find(fa[n]));}void init(int n){ REP(i, n) { fa[i] = i; G[i].clear(); in[i] = 0; } edges.clear();}void AddEdge(int u, int v, int dist){ edges.push_back(Edge(u, v, dist));}void dfs(int u, int fa){ REP(i, G[u].size()) { Edge& e = G[u][i]; if (e.to != fa) { if (e.dist == m * n) cout << e.to + 1 << ' ' << 0 << endl; else cout << e.to + 1 << ' ' << u + 1 << endl; dfs(e.to, u); } }}void solve(){ int ret = 0; sort(all(edges)); REP(i, edges.size()) { Edge& e = edges[i]; int ru = find(e.from), rv = find(e.to); if (ru != rv) { fa[ru] = rv; ret += e.dist; G[e.from].push_back(Edge(e.from, e.to, e.dist)); G[e.to].push_back(Edge(e.to, e.from, e.dist)); in[e.from]++; in[e.to]++; } } WI(ret + n * m); REP(i, k) { if (in[i] <= 1) { cout << i + 1 << ' ' << 0 << endl; dfs(i, -1); break; } }}int judge(int a, int b){ int cnt = 0; REP(i, n * m) cnt += (ipt[a][i] != ipt[b][i]); return cnt;}int main(){// freopen("in.txt", "r", stdin); while (~RIV(n, m, k, w)) { CLR(diff, 0); REP(i, k) { int len = 0; REP(j, n) { RS(ipt[i] + len); len = strlen(ipt[i]); } } REP(i, k) REP(j, k) REP(t, n * m) diff[i][j] += (ipt[i][t] != ipt[j][t]); init(k); REP(i, k) REP(j, k) { if (i == j) continue; AddEdge(i, j, min(diff[i][j] * w, n * m)); } solve(); } return 0;}

转载地址:http://ojsja.baihongyu.com/

你可能感兴趣的文章
方向搜索hdu 1180 诡异的楼梯 楼梯可以变方向的搜索题
查看>>
“快排”笔记
查看>>
vi-4
查看>>
PHP 如何读取一个1G的文件大小
查看>>
Wordpress 3.5.1的debug流水账
查看>>
C#开发一应用的总结
查看>>
setTimeout不断重复执行
查看>>
算法--样本方差、样本标准差、方差、标准方差与加权平均
查看>>
数学建模小练习(1):插值【转】
查看>>
Android开发方向
查看>>
【OpenMesh】使用网格的属性和特征
查看>>
Scrapy开发
查看>>
js获取url参数值
查看>>
cocos2d-x v3.0新特性及使用
查看>>
C#编程总结(二)多线程基础
查看>>
SharePoint Error occurred in deployment step 'Recycle IIS Application Pool': 0x80070005:拒绝访问...
查看>>
escape()、encodeURI()、encodeURIComponent()区别详解 (转)
查看>>
Python 反编译工具uncompyle2
查看>>
LINQ to SQL 建立实体类
查看>>
android存储阵列数据SharedPreferences
查看>>