cynic


私信TA

用户名:202210711108

访问量:2320

签 名:

等  级
排  名 5196
经  验 1578
参赛次数 0
文章发表 10
年  龄 0
在职情况 学生
学  校
专  业 计算机

  自我简介:

TA的其他文章

对于本题样例

虚构地点6连接1,2,3,4,5,从而代替码头的功能(例如1,2,3,建设码头,等价于6站点建设三座联通1,2,3,的道路)

5 5
1 2 4
1 3 -1
2 3 3
2 4 5
4 5 10
-1 10 10 1 1

我们使用kruskal算法:

选取花费最低的路径1-3,此时总花费sum=-1;

已连接站点:1-3

继续取最小值的路径6-4,此时总花费sum=0;

已连接站点:1-3,6-4

继续取最小值的路径6-5,此时总花费sum=1;

已连接站点:1-3,6-4-5

继续取最小值的路径2-3,此时总花费sum=4;

已连接站点:1-2-3,6-4-5

继续取最小值的路径1-2,1和2已连接,不操作

继续取最小值的路径2-4此时总花费sum=9;

已连接站点:1-2-3-4-5-6

故sum=9

特别注意:1.题目所求为最大花费,因此只要道路的花费小于0,不论站点是否已有道路,都应该在建设道路

                 2.如果出现代替码头城市只连接一个站点的情况(即只建了一个码头),应该将改码头的花费减去

                 3.提前对所有道路价值排序(只能用快速排序,否则会超时),且对于码头花费小于0的不进行排序

全代码如下(排序部分抄了大佬作业):

#include<iostream>
#include<vector>
#include <algorithm>
using namespace std;
class Node
{
public:
	int a;
	int b;
	int c;
};
Node node[200001];
int n, m, w;
int fa[100001];
vector<Node>e;
void ini()
{
    for (int i = 1; i <= n+1; i++)
    {
        fa[i] = i;
    }
}
int find(int i)
{
    if (fa[i] == i)
        return i;
    else
    {
        fa[i] = find(fa[i]);
        return fa[i];
    }
}
void unionn(int x,int y)
{
    int _x = find(x);
    int _y = find(y);
    fa[_x] = _y;
}
bool comp(const Node& e1, const Node& e2) {
    return e1.c < e2.c;//从小到大
}
int main()
{
	cin >> n >> m;
    for (int i = 0; i < m; i++)
    {
        cin >> node[i].a >> node[i].b >> node[i].c;
        e.push_back(node[i]);
    }
    int t = m;
    for (int i = 1; i <= n; i++)
    {
        cin >> w;
        if (w != -1)
        {
            node[t].a = n + 1;
            node[t].b = i;
            node[t].c = w;
            e.push_back(node[t]);
            t++;
        }
    }
    sort(e.begin(),e.end(),comp);
    ini();
    int sum = 0;
    int i = 0;
    int j = 0;
    int temp = 0;
    for (; i < e.size(); i++)
    {
        if (e[i].c <= 0)
        {
            if (e[i].a != n + 1)
            {
                sum += e[i].c;
                unionn(e[i].a, e[i].b);
            }
        }
        else
        {
            break;
        }
    }
    for (; i < t; i++)
    {
        if (find(e[i].a) != find(e[i].b))
        {
            if (e[i].a == n + 1)
            {
                j++;
                temp = e[i].c;
            }
            if (j >= 2)
                break;
            sum += e[i].c;
            unionn(e[i].a, e[i].b);
        }
    }
    for (; i < t; i++)
    {
        if (find(e[i].a) != find(e[i].b))
        {
            sum += e[i].c;
            unionn(e[i].a, e[i].b);
        }
    }
    if (j == 1)
        sum-=temp;
    cout << sum;
	return 0;
}


 

0.0分

1 人评分

  评论区

  • «
  • »