레이아웃 POJ - 3169 최단 SPFA 루프 부정 판정 알고리즘 +

다른 사람들처럼, 소 공급을 위해 대기 할 때 자신의 친구에게 가까이 서 좋아합니다. FJ는 N을 갖는다 (2 <= N <= 1000) 소의 사료 대기 직선을 따라 서 1..N으로 번호. 그들이 번호가 같이 소는 동일한 순서로 서, 그들은 오히려 뻔뻔 할 수 있기 때문에, 우리가있는 것으로 각 젖소 생각하면 두 개 이상의 소, 즉 (정확히 같은 위치에 줄 수있는 가능성이있다 일부 수직선상의 좌표 둘 개 이상의 소 동일한 좌표를 공유하는, 다음)은 가능하다. 

서로 같은 일부 소 라인에서 서로 일정한 거리 내에되고 싶어요. 일부는 정말 서로를 싫어하는 적어도 일정한 거리로 구분하고 싶다. ML 목록 (1 <= ML <= 10000) 제약들은 서로 분리 될 수있는 최대 거리 추천하는 암소 설명; MD 제약 후속리스트 (1 <= MD <= 10000)의 소 서로가 분리되어야하는 최소 거리하는 싫어 말한다. 

당신의 임무는 가능하면, 소 1과 거리의 제약 조건을 만족하는 소 N 사이의 가능한 최대 거리를 계산하는 것이다.

입력

행 1 : 세 개의 공간으로 구분 된 정수 : N, ML 및 MD. 

라인 2..ML + 1 <= D 많아야 D (1이어야 A, B, 및 D, 1 <= A <B <= N. 소 A 및 B와 각 라인은 세 개의 공간 분리 된 양의 정수를 포함 <= 1,000,000) 떨어져. 

라인 ML + 2..ML + MD + 1 각 라인은 세 개의 공간 분리 된 양의 정수 포함 A, B, 및 D, 1 <= A <B <= N. 소 A 및 B는 이상이어야 D와를 ( 1 <= D <= 1,000,000) 떨어져.

산출

행 1 : 하나의 정수입니다. 아무 정렬도 가능하지 않으면, 출력 -1. 소 1 및 N 임의로 멀리 떨어져있을 경우, 출력 -2. 젖소 1 N. 사이 그렇지 출력 가능한 최대 거리

샘플 입력

4 2 1 
1 3 10 
2 4 20 
2 3 3

샘플 출력

(27)

힌트

샘플의 설명 : 

4 개 소가 있습니다. 소 # 1과 # 3, 떨어져 # 2 소 10 개 이상 단위 여야합니다 및 # 4는 더 이상 20 이상 떨어져 단위 및 소 # 2, # 3 싫어하는 서로를해야 떨어져 더 미만 3 개 단위 없어야합니다. 

최고 레이아웃은 다수의 라인상의 좌표의 관점에서, 암소 번호 2~7에서, 암소에서 10 # 3 및 # 4 암소 27, 0 암소 # 1을 넣는 것이다.
 
M은 n은 S 점, 점의 두 경우 사이에 문제의 의미를 갖고, n은 (L) 사이의 점 사이의 최대를 나타내고, m은 (S) 사이의 최대 값과 최소 점과 점 L, Q 1을 나타낸다 얼마나 많은 시간.
 
아이디어 : 질문의 의미를 얻을 수있다 : N의 경우 D [1] - D [3] <= 10, D [4] - D [2] <= 20, m 여기서, D [3] - 차원 [ 2]> = 3, 변환에 의해 제 식 D [2] 수득 - D를 [3] <= - 3. 이탈리아는 가장 부정적인 단락을 추구 꽤 잘되도록.
 
코드 :
  1 #INCLUDE <cstdio>
   2 #INCLUDE <fstream>
   3 #INCLUDE <알고리즘>
   4 #INCLUDE <cmath>
   5 #INCLUDE <양단>
   6 #INCLUDE <벡터>
   7 #INCLUDE <큐>
   8 #INCLUDE < 문자열 >
   9 # 포함 <CString을>
 10 #INCLUDE <지도>
 11 #INCLUDE <적층>
 12 #INCLUDE < 설정 >
 13 #INCLUDE <sstream>
 14 #INCLUDE <iostream>
15  #DEFINE 개조 998,244,353
 16  #DEFINE EPS를 1E-6
. 17  #DEFINE LL 긴 롱
 18은  #DEFINE INF의 0x3f3f3f3f가
 19.  은 USING  스페이스 STD,
 20은  
21  // 구조 저장된 부가 정보 
(22)이없는  구조체 노드
 (23)가  {
 24      INT , Y, Z, 다음
 (25)  }
 (26)는 노드 NO [ 10005 ]
 27  // 저장 위치의 에지 
(28)  의 INT 헤드 [ 10005이 ]
 29  // S 포인트의 수를 나타내고, n은 ML의 수는 에지를 나타내는 것이다, m은 MD의 에지 개수 나타내는 
30  의 INT m, S를 N;
 31이다  // ANS는 에지의 개수를 나타낸다 
32  INTANS;
 33이다  //가 다른 시점에 기점의 최소값 나타내고 
있다 (34)  INT DIS [ 10005 ]
 35  // 점의 전류의 최소값이 발견 여부를 판정한다 
(36)  BOOL VIS [ 10005 ]
 37 [  // 현재 위치를 기록하는 여러 찾는 
38  INT CNT는 [ 10005 ]
 39  // 최단 찾아 네거티브 링에게 존재하는지 여부를 판정 
(40)  BOOL SPFA ()
 (41)가  {
 42이다      // 초기화 
43은      큐 < INT > 숨어;
 44이다      qu.push ( 1이다. )
 (45)      가 memset (DIS, INF , sizeof 연산자(DIS))
 (46)는      가 memset (VIS, 0 , sizeof의 (VIS))
 (47)      가 memset (CNT, 0 , sizeof의 (CNT))
 48      // 시작점 초기화 
49      VIS [ 1. =] 1. ,
 50      [DIS . 1 ] = 0 ;
 51      // 큐가 비어있다 출구 
(52)이      그동안 (! qu.empty는 ())
 (53)가      {
 54          // 디큐 
55          INT U = qu.front ();
 56은          qu.pop ();
 (57)가          //지점의 최소값이 변경되므로 접속 포인트의 값도 변화 이것 때문에 
58          VIS를 [유] = 0 ;
 59          // 에지 통과가 U 접속 
60           ( int로 I = 헤드 [U]; ! = I - 1이다. ] I = NO [I]가 다음 내용)
 (61)가          {
 62는              INT에서 V = ; NO는 [I]를 .Y
 63된다              // 최소 업데이트 
64              IF (DIS [V]> DIS [U] + NO [I ] .Z)
 65              {
 66                  DIS [V] DIS [U] + = NO [I] .Z는;
 67                  // 현재 시점 (V)이 표지를 찾을 필요가없는 경우 
68                  IF (! VIS [V])
 (69)                  {
70                      // 마커 점 (V) 
(71)는                      VIS [V] = 1이다. ]
 72                      qu.push (V)
 (73)이다                      // 횟수 탐색 레코드 저장소 
74                      CNT는 [V] ++ ;
 75                      // 개수가 n보다 크면 음의 고리를 나타내고 
76                      IF (CNT [V]> N-)를
 77                      {
 78                           은 false ;
 79                      }
 80                  }
 81              }
 82          }
 83      }
 84  }
 85  INT주 ()
 86  {
 87      는 scanf ( " % D % D % D ' , S, N, m);
88      INT U, V, L;
89      ANS = 1 ;
90      // 初始化
91      memset 함수 (헤드 - 1 , 를 sizeof (헤드));
92      // 正向记录边
93       ( int로 I = 1 ; i가 <= N; ++ i가 )
 94      {
 95          는 scanf ( " % D % D % D ' , U, V, L);
(96)          에는 [ANS] .Y = 없음V;
(97)          에는 [ANS] .Z =의 L 없다;
98          없음 [ANS] 다음 내용 = 헤드 [U];
99          헤드 [U] = 된 ANS ++ ;
100      }
 101      // 反向记录边
102       ( int로 I = 1 ; I <= m; 내가 ++ )
 103      {
 104          는 scanf ( " % D % D % D ' , U, V, L)를;
105          에는 [ANS] .Y = U;하지
106          없음 [ANS] .Z = - L;
107          없음 [ANS] 다음 내용 = 헤드 [V];
108          헤드 [V] = ANS ++,
 109      }
 (110)      // 더 루프 네거티브 출력 솔루션 -1 출력 -2를 나타내는 많은 경우가 무한 용액은 용액 출력 용액 없다 있으면 
111      IF (SPFA ())
 (112)      {
 113          IF (DIS [S] == INF)
 (114)          {
 115              의 printf ( " -2 \ N- " )
 (116)          }
 (117)          다른 
1 18          {
 119              의 printf ( " % D의 \의 N- ' , DIS [S])
 (120)          }
 (121)      }
 (122)      다른 
123      {
 124          의 printf (" -1 \ 없음 " );
125      }
 126  
127 }

 

추천

출처www.cnblogs.com/mzchuan/p/11568371.html