• [解题报告]ural 1041 Nikifor


    Abstract

    ural 1041

    贪心 矩阵胚

    Body

    Source

    http://acm.timus.ru/problem.aspx?space=1&num=1041

    Description

    给定M个N维带权向量。求这些向量中的一个极大无关组(显然有N个向量),使得其权值和最小。

    Solution

    设S为所有给定的向量,I为这些向量构成的所有线性无关组。则M=(S,I)为一矩阵胚(算法导论翻译为拟阵),因此可采用贪心算法。将所有向量按权值从小到大排序,当前向量能加入解集就加入(与当前解集线性无关),否则舍弃。具体证明以后再写。判断线性相关用高斯消元,将当前向量每一维能消成0的消成0,如果最后不全为0就是线性无关。注意不要用浮点数,运算对质数取模即可。

    因为下意识地以为会spj没看到要输出字典序最小的WA了整个晚上……

    Code

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <utility>
    #include <vector>
    #include <algorithm>
    using namespace std;

    typedef long long LL;

    const LL MOD = 971027;
    const int MAXN = 55;

    struct sv {int id, cost;}v[2020];
    bool operator<(const sv &v1, const sv &v2)
    {
    if (v1.cost==v2.cost) return v1.id<v2.id;
    return v1.cost < v2.cost;
    }

    int M, N;
    LL a[2020][MAXN];
    int first[2020];
    int ref[55];
    int cost;
    vector<int> ans;

    LL gcd(LL p, LL q)
    {
    LL r;
    while (q)
    {
    r = p%q;
    p = q;
    q = r;
    }
    return p;
    }

    int gauss(int i)
    {
    int j, k;
    for (j = 0; j < N; ++j)
    {
    if (a[i][j]==0) continue;
    if (ref[j]==-1) return j;
    LL t = gcd(abs(a[i][j]), abs(a[ref[j]][j]));
    LL p = a[ref[j]][j]/t, q = a[i][j]/t;
    for (k = j; k < N; ++k)
    a[i][k] = (a[i][k]*p-a[ref[j]][k]*q)%MOD;
    }
    return -1;
    }

    int main()
    {
    int i, j, k;
    scanf("%d%d", &M, &N);
    for (i = 0; i < M; ++i)
    for (j = 0; j < N; ++j)
    scanf("%lld", &a[i][j]);
    for (i = 0; i < M; ++i)
    {
    scanf("%d", &v[i].cost);
    v[i].id = i;
    }
    sort(v, v+M);
    memset(ref, 255, sizeof(ref));
    for (i = 0; i < M; ++i)
    {
    j = gauss(v[i].id);
    if (j != -1)
    {
    ref[j] = v[i].id;
    cost += v[i].cost;
    ans.push_back(v[i].id+1);
    }
    if (ans.size()==N) break;
    }
    if (ans.size()<N)
    puts("0");
    else
    {
    printf("%d\n", cost);
    sort(ans.begin(), ans.end());
    for (i = 0; i < N; ++i)
    printf("%d\n", ans[i]);
    }
    return 0;
    }



    Reference

  • 相关阅读:
    python execfile
    ubuntu速度慢的原因之内存和swap分区
    AFAIK=as far as i know
    Python中静态方法的实现
    KirbyBasepure python text database
    A Novel Approach to Data Retrieval and Instrumentation Control at Remote Field Sites using Python and Network News
    stackoverflow将成我的新的csdn

    Lynx
    mutliprocessing
  • 原文地址:https://www.cnblogs.com/jffifa/p/2291392.html
Copyright © 2020-2023  润新知