1>グループ
互いに素設定仮想点+
私は、ブリッジとして敵とブリッジとして変換関係をnと+
友人の友人は友人である、友人の敵は敵であります
敵の敵は私の友人である、敵は友達の敵です
書式#include <cstdioを> する#include <cstdlib> 書式#include <iostreamの> 使用して 名前空間はstd; INTの N、M。char型のC; const int型 N = 1003 ; INT FA [N << 1 ]。 BOOL VIS [N << 1 ]。 int型を見つける(int型x)は { 返す FA [x]はx:FA [X] =!?(FA [X])を見つけます。} ボイドマージ(INT U、INT V) { U =検索(U)、V = (V)を求めます。 もし(U!= v)のFA [U] =V; } int型のmain() { scanfの(" %のDの%のD "、およびN-、&M); INT U、V、 のための(int型私は= 1 ; I <= M、Iが++ ) { CIN >> C; scanfの(" %のDの%のD "、&U&V); IF(C == ' F.が' ) (u、v)は、マージマージ(U +、N-、N-V +); // 間違ったフレーズを再度追加、しかし私は追加したい 他の マージを(V + N-、U)、マージ(U + N-、V); } int型= ANS 0 ; のための(INT I = 1 ; I <= N - 、Iは++)// Dianxuan文言、上記のシーケンスが組み合わさ必要である> N - > <N! IF ANS ++(!FA [I]); のprintf(" %d個の\ N- " 、ANS); の戻り 0 ; }
2>投獄犯罪者
互いに素設定仮想点+
同上のアイデア
書式#include <cstdioを> する#include <cstdlib> 書式#include <アルゴリズム> 使用して 名前空間はstdを、 INTのN、M。 CONSTの INT N = 20003、M = 100003 。 INT FA [N << 1 ]。 int型を見つける(int型x)は { 返す FA [x]はx:FA [X] =!?(FA [X])を見つけます。} ボイドマージ(INT U、INT V) { U =検索(U)、V = (V)を求めます。 もし(!U = V)FA [U] = V; } 構造体ノード { int型Uを、V、W。 ブール 演算子 <(constのノード&O)のconst { 戻り W> OW。} } G [M]。 INT メイン() { scanf関数(" %d個の%のD "、&N、&M)。 以下のために(int型 I = 1 ; I <= M iは++ ) のscanf(" %D%D%D "、&G [i]は.U、&G [i]は.V、&Gを[I] .W)。 ソート(G + 1、G + M + 1 )。 以下のための(int型 I = 1; I <= M; iが++ ) { int型 FU =(グラム[I] .U)、FV =見つける検索(G [i]は.V)。 もし(FU == FV) { のprintf(" %d個の\ n " 、G [i]が.W)。 リターン 0 ; } 他 (FU、G [i]は.Vマージ + N)、マージ(FV、G [i]は.U + N)。 } のprintf(" 0 \ n " ); リターン 0 ; }
方法2:バイナリ算術
単調性から被写体のことを考え、
チェックアウトは、裁判官二部グラフを染色することによって書かれています
書式#include <cstdioを> する#include <cstdlib> 書式#include <アルゴリズム> 書式#include <CStringの> の#include <ベクトル> の#include <キュー> 使用して 名前空間はstdを、 INTのN、M。 CONSTの INT N = 20003、M = 100003 。 構造体ノード { int型U、V、W。 ブール 演算子 <(constのノード&O)のconst { リターン <W OW。} } G [M]。 構造体ND { int型V、W。 ND(INT VV、INT WW) {V = VV、W = WW;} ND(){} }。 ベクター <ND> SD [N]。 int型ST [N]; ブールチェック(INT MID) { memsetの(ST、0、はsizeof (ST))。 INT MX = G [中間] .W。 キュー < 整数 > Q; 用(int型 i = 1 ; iが<= N iが++ ) 場合(!ST [I]) { ST [I] = 1 。 q.push(I)。 一方、(!q.empty()) { int型 T = q.front(); q.pop()。 INT SZ = SD [T] .size()。 用(INT J = 0 ; J <SZ、J ++ ) { 場合(SD [T] [J] .W <= MX || ST [SD [T] [J] .V] + ST [T] == 3)継続; もし(ST [SD [T] [J] .V] == ST [T])を返す 偽。 ST [SD [T] [J] .V] = 3 - ST [T]。 q.push(SD [T] [J] .V)。 } } } 戻り 真。 } int型のmain() { scanf関数(" %D%dの"、&N、&M)。 以下のために(int型 I = 1 ; I <= M iは++ ) { scanf関数(" %D%D%D "、&G [i]は.U、&G [i]は.V、&Gを[I] .W)。 SD [G [i]は.U] .push_back(ND(G [i]が.V、G [i]が.W))。 SD [G [I] .V] .push_back(ND(G [i]が.U、G [i]が.W))。 } ソート(G + 1、G + M + 1 )。 INTは L = 0、R = M +1 ; 一方、(L <= R) { int型ミッド=(L + R)>> 1 。 もし R =ミッド((MID)をチェックしてください)1 。 他リットル=ミッド+ 1 ; } のprintf(" %d個の\ n " 、G [L] .W)。 リターン 0 ; }
3>