題目給出一些點對之間的權值,要求把點對分到兩個集合之中,使得兩個集合中的最大邊的值最小。我們考慮到將點對分成兩個集合可以用並查集的分集合方法得到,1-n表示的是乙個集合,n+1-2*n表示的是另乙個集合,因為我們不會人為的將x和x+n合併,所以x+n所在集合與x所在的集合一定是相互排斥的,也就是說x+n集合是所有不和x乙個集合的結點構成的集合。本題只要貪心地掃一遍最大邊就可以。將邊排序之後我們逐個選擇最大邊,分為兩種情況。
1、如果最大邊的兩個結點不在同乙個集合中,我們就把他分到兩個集合中,因為如果合併到乙個集合之中就已經結束了,但是接下來可能會有更小的邊滿足條件,所以分在兩個集合之中。
2、如果最大邊的兩個結點已經在同乙個集合中,這條邊就是答案,因為他們已經是某個集合中的最大邊,而且兩個集合中已經沒有任何一條邊比它大。此時就實現了最大邊的最小化。
**如下:
1 #include2using
namespace
std;
3 typedef unsigned int
ui;4 typedef long
long
ll;5 typedef unsigned long
long
ull;
6#define pf printf
7#define mem(a,b) memset(a,b,sizeof(a))
8#define prime1 1e9+7
9#define prime2 1e9+9
10#define pi 3.14159265
11#define lson l,mid,rt<<1
12#define rson mid+1,r,rt<<1|1
13#define scand(x) scanf("%llf",&x)
14#define f(i,a,b) for(int i=a;i<=b;i++)
15#define scan(a) scanf("%d",&a)
16#define mp(a,b) make_pair((a),(b))
17#define p pair18
#define dbg(args) cout<<#args<<":"<19
#define inf 0x3f3f3f3f
20const
int maxn=1e6+10;21
intn,m,t;
22 inline int
read()
26while(isdigit(ch))ans=(ans<<3)+(ans<<1)+ch-'
0',ch=getchar();
27return ans*w;28}
29struct
nodep[maxn];
32int
f[maxn];
33void
init()
3437
int find(int
x )38
41bool cmp(node& a,node&b)
4245
intmain()
4656 sort(p+1,p+m+1
,cmp);
57 f(i,1
,m)58
66else
6771
}72 pf("0"
);73
return0;
74 }
洛谷p1525 並查集
先將最大的犯罪都找出來然後將人員分組 假設兩人x,y 如果x 前面已經有過敵人了 那就將y合併到x的敵人裡去 y也是如此若有 將x合併到y的敵人去 如果x 和 y前面都沒有 那麼互相將彼此設為敵人 直到找到矛盾的 就是 xy有同乙個敵人 include include include using n...
並查集 洛谷P1525 關押罪犯
我以前學的是假的並查集 這個題目有很明顯的歸屬關係,可一用並查集搞一搞 普遍來說有兩種方法 1.權值並查集 2.拆點並查集 我們乙個乙個來 當然他們的共同條件就是要先把邊按權值遞減排序,不斷加入,直到無法避免矛盾,那麼直接輸出答案 權值並查集 這個很難解釋啊 我們定義如果x,y相連,那麼代表他們在不...
洛谷OJ P1525 關押罪犯(種類並查集)
s 城現有兩座監獄,一共關押著 nn 名罪犯,編號分別為 1 n1 n。他們之間的關係自然也極不和諧。很多罪犯之間甚至積怨已久,如果客觀條件具備則隨時可能爆發衝突。我們用 怨氣值 乙個正整數值 來表示某兩名罪犯之間的仇恨程度,怨氣值越大,則這兩名罪犯之間的積怨越多。如果兩名怨氣值為 cc 的罪犯被關...