这道题其实就是求去掉某节点后的最小生成树的长度,取最大的长度的序号进行输出,如果所有序号最小生成树长度都为0,则输出0
#include<iostream>
#include<vector>
#pragma warning(disable:4996)
using namespace std;
int N, M, s_max = 0;
vector<int> re;
int arc[505][505];
vector<int> x;
vector<int> te;
void ins(int t)
{
for (int i = 1;i <= N;i++)
if (i != t) x.push_back(i);
}
int main()
{
for (int t = 0;t < 505;t++)
for (int i = 0;i < 505;i++)
arc[t][i] = 0x3f3f3f3f;
cin >> N >> M;
while (M--)
{
int a, b, c, d;
scanf("%d %d %d %d", &a, &b, &c, &d);
if (d) arc[a][b] = arc[b][a] = 0;
else arc[a][b] = arc[b][a] = c;
}
for (int t = 1;t <= N;t++)
{
x.clear();te.assign(N + 1, -1);
ins(t);
int f = x.back();x.pop_back();
for (int i = 0;i < x.size();i++)//初始化
te[x[i]] = arc[f][x[i]];
int eff = 0;
while (!x.empty())//最小生成树
{
int min_s = 0x3f3f3f3f;int v = 0;
for (int i = 0;i < x.size();i++)
{
if (min_s > te[x[i]])
{
min_s = te[x[i]];
v = i;
}
}
if (min_s == 0x3f3f3f3f) { eff = min_s;break; }
eff += min_s;
int ttt=x[v];
x.erase(x.begin() + v);
v = ttt;
for (int i = 0;i < x.size();i++)
if (arc[v][x[i]] < te[x[i]])
te[x[i]] = arc[v][x[i]];
}
if (eff> s_max)
{
s_max = eff;
re.clear();
re.push_back(t);
}
else if (eff == s_max)
re.push_back(t);
}
if (s_max == 0 && re.size() == N) {
cout << 0 << endl;exit(0);
}
cout << re[0];
for (int t = 1;t < re.size();t++)
cout << " " << re[t];
cout << endl;
}
该问题涉及图论中的最小生成树概念,需要找到一个节点,当它被删除后,剩余部分形成的最小生成树的边权之和最大。若所有节点移除后最小生成树长度均为0,则输出0。
1075

被折叠的 条评论
为什么被折叠?



