就是一道很简单的并查集,其实写完用不了多少时间。
但有几个地方需要注意:
1.我们不能把集合想想成两个监狱集合,而是储存一个enemy,否则会出现一个问题:
当我们新枚举两个犯人时,如果这两个犯人都没有出现过,我们就不知道应该把这两个人放在哪,而且这个放法一定会对之后的结果造成影响,所以必须要enemy数组,进行转换。
2.就是对于0的输出……
另外这是道贪心,因为我们要尽可能地把两个仇恨值大的犯人分开。
代码:
#include<cstdio> #include<algorithm> using namespace std; #define maxn 100005 int enemy[maxn]; struct node { int x,y,c; } q[maxn]; int n,m,ans,par[maxn]; bool cmp(node a,node b) { return a.c>b.c; } int find(int x) { return x ==par[x] ? x : par[x]=find(par[x]); } void merge(int x,int y) { par[find(x)]=find(y); } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) par[i]=i; for(int i=1;i<=m;i++) scanf("%d%d%d",&q[i].x,&q[i].y,&q[i].c); sort(q+1,q+1+m,cmp); for(int i=1;i<=m;i++) { if(find(q[i].x)==find(q[i].y)) { ans=q[i].c; break; } else { if(enemy[q[i].x]==0) enemy[q[i].x]=q[i].y; else merge(q[i].y,enemy[q[i].x]); if(enemy[q[i].y]==0) enemy[q[i].y]=q[i].x; else merge(q[i].x,enemy[q[i].y]); } } printf("%d",ans); return 0; }