効果の件名:
、互いに素-セットで開始することが困難な代表要素ユニコムブロックを維持するために見つけ、その全体の検索を使用して、オープン配列は、そのメンテナンスのプライオリティキューを開く揚げされ、各ユニコムSaowanブロックは、統計的な答えは、プライオリティキューをクリア!!念頭に置いて、アレイ注の大きさを保つください!!!
コード:
書式#include <cstdioを>
する#include <iostreamの>
の#include <cstdlib>
書式#include <アルゴリズム>
書式#include <CStringの>
の#include <キュー>
の#define int型はlong long
の#define N 1005000
名前空間stdを使用。
N INT、M、L、ヴァル[N]、ヘッド[N]、CNT、TOT、ANS。
INTのSIZ [N]。
VIS [N] BOOL。
{NXTにINT;}構造体ノードE [N]。
読み取りINT()
{
int型のx = 0、F = 1。
チャーCH = GETCHAR()。
一方、(CH < '0' || CH> '9'){IF(CH == ' - ')は、f = -1; CH = GETCHAR();}
一方(CH> = '0' && CH <= '9 '){X = X * 10 + CH-'0'; CH = GETCHAR();}
戻りのx * Fを、
}
ボイド追加(int型、intへの)
{
E [++ CNT] =(ノード){に ヘッド}から]。
ヘッド= CNT [から]。
}
キュー<整数> Q;
PRIORITY_QUEUE <整数>をDij。
ボイドBFS(int型X)
{
VIS [X] = 1。
int型SIZ = 0;
SIZ + =(valの[X] -1)。
ANS + = X。
dij.push(X)。
q.push(X)。
(!q.empty())しばらく
{
int型S = q.front();
q.pop();
(I =ヘッド[S]をint型; I; I = E [I] .nxt)は
{
int型、Y = E [I] .TO。
IF(!VIS [Y]){
VIS [Y] = 1。
q.push(Y)。
SIZ + =(ヴァル[Y] -1)。
dij.push(Y)。
ANS + = Y。
}
}
}
ながら(SIZ){
int型XX = dij.top()。dij.pop();
IF(SIZ <= L-1)
{
ANS + = SIZ * XX。
SIZ = 0;
}
IF(SIZ>(L-1))
{
SIZ - =(L-1)。
ANS + = XX *(L-1)。
}
}
一方(dij.size())dij.pop();
}
)(主符号付き
{
#ifdefのyilnr
の#else
freopenは( "pmlaw.in"、 "R"、STDIN)。
freopenは( "pmlaw.out"、 "W"、STDOUT)。
#endifの
)(L =読み取る; = M()を読み出す; N =()を読み込みます。
用)(valは[i]を読み出す=(int型i = 1; iが++; iが<= N)。
以下のための(I = 1、X、Y int型、iが<= M; iは++)
{
scanf関数( "%のLLDの%のLLD"、およびX&Y)を、
(x、y)を追加し、(x、y)を加えます。
}
場合BFS(i)について(iは++; iがn = <I = 1 INT)(VIS [I]!)。
printf( "%LLDする\ n"、ANS)。
FCLOSE(STDIN); FCLOSE(STDOUT)。
0を返します。