题目链接:https://ac.nowcoder.com/acm/problem/16591
分析:
因为市长只看最大影响力,所以我们将影响力从大到小排序,尽可能的去将会发生大影响的冲突避免(即将两个人分到两个监狱里面)
下面解释一句话,敌人的敌人是朋友————
假如 a和b会产生冲突,由于我们是将数组按照影响力从大到小排序的,所以我们要去尽可能避免a和b发生冲突,将a和b分到两个监狱去,这时候假如又告知你,b和c会产生冲突,那么为了避免b和c的冲突,你很自然的会把c放到和a一个监狱里。把a和c放到一个监狱里,就形成了类似敌人的敌人是朋友的观念。但是如果他下文在告诉你a和c会发生矛盾,
那么这个a和c的矛盾就是不可避免的了,由于a和b 以及 b和c是先出现的所以影响力一定会大于a和c,所以a和c不可避免出现冲突,就是最小的最大影响力了。
细节和重点看代码和注释吧!
#include<iostream> #include<algorithm> #include<queue> #include<string> #include<cstdio> #include<cstring> #include<queue> #include<vector> #include<stack> #include<set> #include<map> #define ll long long using namespace std; #define close_stdin ios::sync_with_stdio(false) int n, m; int fa[20005]; int b[20005];//表示i的敌人是谁 (敌人的敌人是朋友) struct node { int u, v; ll w; }a[100005]; //并查集常用操作 merge 与find int find(int x) { return(fa[x]==x?x:fa[x]=find(fa[x])); } void merge(int x, int y) { fa[find(x)] = find(y); } bool cmp(node a,node b) { return (a.w > b.w); } void my_input() { cin >> n >> m; for (int i = 1;i <= m;i++) { cin >> a[i].u >> a[i].v >> a[i].w; } } void solve() { for (int i = 1;i <= n;i++) { fa[i] = i; } sort(a + 1, a + 1 + m, cmp);// 按照影响力从大到小排序 for (int i = 1;i <= m;i++) { if (find(a[i].u) == find(a[i].v)) { cout << a[i].w << "\n";return; } //冲突不可避免 由于是从大到小排序 这就是最大冲突了。 if (!b[a[i].u]) { b[a[i].u] = a[i].v; } // 把u的敌人v 和u在b数组中的存的敌人 建立 朋友关系 else merge(a[i].v, b[a[i].u]); if (!b[a[i].v]) { b[a[i].v] = a[i].u; } //// 把v的敌人u 和v在b数组中的存的敌人 建立 朋友关系 else merge(a[i].u, b[a[i].v]); } cout << "0\n"; return; } int main() { close_stdin;//只是为了让cin和printf一样快 my_input(); solve(); }
谢谢浏览哈!