做成最短路了,过了不少样例,求证伪思路或者指正为什么有两个点没过
  • 板块P9688 Colo.
  • 楼主z__y
  • 当前回复1
  • 已保存回复1
  • 发布时间2023/10/6 23:39
  • 上次更新2024/1/6 16:04:09
查看原帖
做成最短路了,过了不少样例,求证伪思路或者指正为什么有两个点没过
843121
z__y楼主2023/10/6 23:39
#include<iostream>
#include<unordered_map>
#include<vector>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn = 1000200;

                 //记录每种数字后面出现了哪些种类的数字
unordered_map<int, vector<int>>behind;
//如果i<j,且behind[i]中有j且behind[j]中没有i,那么就可以增加一条i->的边

struct Edge {
    long long a;
    long long b;
    long long c;                               //表示权重,这里就是w[b]的负数
};

bool cmp(Edge x, Edge y)
{
    return x.a < y.a;
}
long long v[maxn], w[maxn];
vector<long long >nums;                        //记录出现了哪些种类的颜色
vector<Edge>edges;
unordered_map<long long, long long> st;                            //记录到每个颜色最短路的边数
unordered_map<long long,long long> dist, backup;
unordered_map<long long, long long>backst;
void bellman_ford(int m, int k)                            //m表示一共有m个边,k表示要求的是长度为k的路
{
    

    dist[0] = 0;

    for (int i = 0; i < k; i++)
    {
        backup = dist;
        backst = st;
        

        for (int j = 0; j < m; j++)
        {
            long long a = edges[j].a, b = edges[j].b, c = edges[j].c;

            if (dist[b] >backup[a] + c)
            {
                dist[b] = backup[a] + c;
                st[b] = backst[a] + 1;
            }
        }
    }


}

int main()
{
    int n, k;
    cin >> n >> k;
    unordered_map<int, int>mp;           //记录有没有出现过
    for (int i = 1; i <= n; i++)
    {
        cin >> v[i];
        if (mp.count(v[i]) == 0)
        {
            nums.push_back(v[i]);
            mp[v[i]]++;
        }
    }
    for (int i = 1; i <= n; i++)
    {
        cin >> w[i];
    }
    sort(nums.begin(), nums.end());

    if (nums.size() <= k)
    {
        cout << -1 << endl;
        return 0;
    }
    unordered_map<int, int>mpp;
    for (int i = 1; i <= n; i++)
    {
        if (mpp.count(v[i]) != 0)
        {
            continue;
        }
        else
        {
            mpp[v[i]]++;
        }
        unordered_map<int, int>mp1;
        for (int j = i + 1; j <= n; j++)
        {
            if (mp1.count(v[j]) == 0 && v[j] != v[i])
            {
                behind[v[i]].push_back(v[j]);
                mp1[v[j]]++;
            }
        }
    }

    for (int i = 0; i < nums.size(); i++)
    {
        for (int j = i + 1; j < nums.size(); j++)
        {
            auto it1 = std::find(behind[nums[i]].begin(), behind[nums[i]].end(), nums[j]);
            auto it2 = std::find(behind[nums[j]].begin(), behind[nums[j]].end(), nums[i]);

            if (it1 != behind[nums[i]].end() && it2 == behind[nums[j]].end())
            {
                edges.push_back({ nums[i],nums[j],-w[nums[j]] });
            }
        }
    }

    for (int i = 0; i < nums.size(); i++)
    {
        edges.push_back({ 0,nums[i],-w[nums[i]] });                          //建立一个0点,然后求从0到任何一个点经过k个边的最短路
        //dist[nums[i]] = -w[nums[i]];
        //st[nums[i]] = 1;
    }
    sort(edges.begin(), edges.end(),cmp);
    bellman_ford(edges.size(), k);
    long long res = 1e11;
    for (int i = 0; i < nums.size(); i++)
    {
        if (st[nums[i]] <k)
        {
            continue;
        }
        else
        {
            res = min(res, (long long)dist[nums[i]]);
        }
    }

   

    if (res >= 1e11)
    {
        cout << -1 << endl;
    }
    else
    {
        cout << -res << endl;
    }
    return 0;

}
2023/10/6 23:39
加载中...