Luogu P1525 关押罪犯
思路
这道题和同伙那道题差不多啊。都是利用并查集的补集来实现将敌人分开
这道题不一样的地方就是需要小小的贪个心。不难想到我们要使得怨恨值越大的两个罪犯尽量分开住,那么就按照边权从大到小进行排序。然后把敌人并到自己的补集中去。
知道有两个罪犯不得不被关在一起的时候。直接输出这条边的边权,结束程序。如果一直找不到的话,就证明没有纠纷发生,那就输出0
吐槽
警察局长应该要被开除了QwQ
代码
#include <iostream> #include <cstring> #include <cstdio> #include <algorithm> const int maxnode = 2e4+3; const int maxedge = 1e5+3; using namespace std; int f[maxnode], n, m, x, dig, enm[maxnode], xx, yy; char c; struct edge { int u, v, w; }ed[maxedge]; inline int read() { x = 0, dig = 1; c = getchar(); while (c < '0' || c > '9') { if(c == '-') dig = -1; c = getchar(); } while (c <= '9' && c >= '0') { x = x*10 + c-'0'; c = getchar(); } return x * dig; } inline int find(int x) { return (f[x] == x) ? x : (f[x] = find(f[x])); } bool cmp(edge a, edge b) { return a.w > b.w; } int main() { n = read(), m = read(); for(int i=1; i<=n; i++) { f[i] = i; } for(int i=1; i<=m; i++) { ed[i].u = read(), ed[i].v = read(), ed[i].w = read(); } sort(ed+1, ed+1+m, cmp); for(int i=1; i<=m; i++) { if(find(ed[i].u) == find(ed[i].v)) { printf("%d", ed[i].w); return 0; } else { if(enm[ed[i].u] == 0) enm[ed[i].u] = ed[i].v; xx = find(ed[i].v), yy = find(enm[ed[i].u]); if(xx != yy) f[xx] = find(yy); if(enm[ed[i].v] == 0) enm[ed[i].v] = ed[i].u; xx = find(ed[i].u), yy = find(enm[ed[i].v]); if(xx != yy) f[xx] = find(yy); } } printf("0"); }
作者:Mystical-W
来源:http://www.cnblogs.com/bljfy
说明:客官~~您如果觉得写得好的话,记得给我点赞哦。如果要转载的请在合适的地方注明出处。谢
谢您的合作。您要是有什么有疑问的地方可以在下面给我评论。也可以直接私信我哦
声明:本作品由Mystical-W采用知识共享署名-非商业性使用-禁止演绎 4.0 国
际许可协议进行许可
来源:http://www.cnblogs.com/bljfy
说明:客官~~您如果觉得写得好的话,记得给我点赞哦。如果要转载的请在合适的地方注明出处。谢
谢您的合作。您要是有什么有疑问的地方可以在下面给我评论。也可以直接私信我哦
声明:本作品由Mystical-W采用知识共享署名-非商业性使用-禁止演绎 4.0 国
际许可协议进行许可