効果:西から東へ順番には、$ N $戻って東に、その後の都市、双方向与えられたの$ M $のエッジストリップ、航空路を求めて、西へ東から最も満足と最も、互いの開始点に加えを与えますほとんどが一度行き、通りの都市の最大数。
$ 1から$ $ $ N-ん交わらない、通過に必要なポイント数の最大値から二つの経路を見つけることと等価です。
図MFMCは最後の二つのDFS出力パスを実行するために構築されました。
書式#include <iostreamの> の#include <sstream提供> する#include <アルゴリズム> 書式#include <cstdioを> する#include <math.h>の 書式#include <設定> 書式#include <マップ> 書式#include <キュー> の#include <string>に する#include < string.hの> の#include <ビットセット> の#include <unordered_map> の#define REP(I、N)のために(INT iは=; I <= N; ++ I) の#define PER(I、N) - (I; I> = A I = N INT)のため の#defineのHRのputchar(10) の#define PB一back の#define LC(O << 1) (| 1 LC)の#define RC の#define中間((L + R)>> 1) の#define LSのLC、L、中 の#define RSのRC、ミッド+ 1、R の#define X最初 の#define yの第二 の#define IOのstd :: IOS :: sync_with_stdio(偽) の#define ENDL '\ n'は #define DB(A)({REP(__ I、1、n)はCOUT << [__ I] <<」「;}時間) 名前空間stdを使用。 typedefの長い長いLL。 typedefのペア<int型、int型> PII。 CONST int型P = 1E9 + 7、P2 = 998244353、INF = 0x3f3f3f3f。 LLのGCD(-1,11,11- b)は{戻りB GCD(B、%のB):;} のLL qpow(-1,11,11- n)で{LLのR = 1%P;(%= Pのために、N ; = *%P、N >> = 1)であれば(N - 1)R = R *%のP、リターンR;} ?LL INV(LL X){X <= 1を返す:INV(P%以下X)*(PP / X)%P;} インラインint型RD(){int型のx = 0; CHAR P = GETCHAR();一方、(P < '0' || P> '9')p = GETCHAR() ;一方、(P> = '0' && P <= '9')、X = X * 10 + P-'0' 、P = GETCHAR();戻りX;} //ヘッド のconst int型N = 1E6 + 10。 N INT、M、S、T。 構造体_ {から、F、W、にINT;}; ベクトル<_> E; ベクトル<整数> G [N]。 キュー<整数> Q; INT [N]、プリ[N]、INQ [N]、D [N]。 int型MF、MC。 【e.to] =分([X]、EW)。 ボイド追加(int型のx、int型のY、int型C、INT W){ G [X] .pb(E.size())。 E.pb({X、Y、C、W})。 G [Y] .pb(E.size())。 E.pb({Y、X、0、-w})。 } ボイドMFMC(){ MF = MC = 0。 (1){一方 REP(I、1、T)[i]は= Dの[I] = INF、INQ [I] = 0; q.push(S)、D [S] = 0; 一方、{(q.empty()!) INT X = q.front()。q.pop(); [X] INQ = 0。 以下のための(自動T:G [X]){ オートE = E [T]。 IF(EW> 0 && D [e.to]> D [X] + EF){ D [e.to] = D [X] + EF。 事前[e.to] = T。 もし{(INQ [e.to]!)[e.to] = 1 INQ。 q.push(e.to)。 } } } } もし([T] == INF)ブレーク。 (INT U = T; U = S;!Uは= E [U]は[事前]から。)のために{ E [プレ[U] W- = A [T]。 E [プレ[U] ^ 1] .W + = [T]。 } MF + = [T]、MC + = [T] * D [T]。 } } マップ<文字列、整数> F。 ストリングヴァル[N]。 INTのID(文字列s){ IF(f.count(S))リターンF [S]。 INT T = f.size()+ 1。 ヴァル[T] = sで、 [S] = T F返します。 } ベクトル<ストリング> V1、V2。 ボイドDFS(INT X、ベクトル<ストリング>&V){ IF(1 <= X && X <= N)v.pb(ヴァル[X])。 {(G [x]は自動T)のための IF(T%2 == 0 && E [T ^ 1] .W){ --E [T ^ 1] .W。 戻りDFS(E [T] .TO、V)。 } } } int型のmain(){ scanf関数( "%D%dの"、&N、&M)。 REP(I、1、N){ 文字列s。 CIN >> S、ID(S); } REP(I、1、M){ 文字列X、Y。 CIN >> X >> Y。 (ID(X)+ nは、ID(Y)、INF、0)を加えます。 } REP(I、1、n)の追加(?I、iはiがN == == 1 ||、N 2 + 1、-1)。 S = 2 * N + 1、T = Sを+ 1。 、(N、T、INF、0)を追加(0、S 1、INF)を追加します。 MFMC(); もし(MF = 2!)戻りプット( "いいえソリューション!")、0; printf( "%d個の\ n"、-mc)。 DFS(1、V1)、DFS(1、V2)。 以下のための(自動T:V1)はcout <<トン<<てendl; 用(オートトン= v2.rbegin();!T = v2.rend(); ++トン)はcout << *トン<<てendl; }