您的位置:首页 > 其它

HDU 1598 find the most comfortable road

2017-04-08 21:46 459 查看
传送门

这题不会,记住写法就行了,好像都是这么写的?

第一次从最小边开始往上添,第二次从第二小边开始。。。每次添边直到那俩点连通,每次记录该次的极差并更新最优值。

可得到的结论是,第
i+1
次添的最后一条边肯定不会比第
i
次添的最后一条边权值还小。

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

const int INF = 1e9;
const int MAXN = 205;
int N, M, Q;
int opt;

struct Edge
{
int n1, n2, sp;
bool operator<(const Edge& e) const
{
return sp < e.sp;
}
};
vector<Edge> v;
int pre[MAXN];

int f(int x)
{
int f0 = x, f1 = x;
for (; pre[f0] > 0;)
f0 = pre[f0];
for (; pre[f1] > 0;)
{
int t = f1;
f1 = pre[f1];
pre[t] = f0;
}
return f0;
}

void u(int n1, int n2)
{
int f1 = f(n1);
int f2 = f(n2);
if (f1 != f2)
{
if (pre[f1] <= pre[f2])
{
pre[f1] += pre[f2];
pre[f2] = f1;
}
else
{
pre[f2] += pre[f1];
pre[f1] = f2;
}
}
}

int main()
{
int a, b, c;
bool flag;
for (; ~scanf("%d%d", &N, &M);)      // 别忘加 ~
{
v.clear();
for (int i = 0; i < M; i++)
{
scanf("%d%d%d", &a, &b, &c);
v.push_back({ a,b,c });
}
sort(v.begin(), v.end());
scanf("%d", &Q);
for (int i = 0; i < Q; i++)
{
flag = false;
opt = INF;
scanf("%d%d", &a, &b);
for (int j = 0; j < v.size(); j++)
{
memset(pre, -1, sizeof pre);
for (int k = j; k < v.size(); k++)
{
u(v[k].n1, v[k].n2);
if (f(a) == f(b))
{
opt = min(opt, v[k].sp - v[j].sp);
break;
}
if (k == v.size() - 1) flag = true;
}
if (flag) break;
}
if (opt == INF) printf("-1\n");
else printf("%d\n", opt);
}
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: