도로 와 항로 (SPFA 알고리즘) (Bellman - ford 알고리즘 최적화)
모든 도로 i 또는 항로 i 는 도시 와 읍 을 연결 하 는 Ai (1 & lt; A i & gt; = T) 와 Bi (1 & lt; = Bi & gt; = T) 의 대 가 를 Ci 로 표시 한다.모든 도로 에서 Ci 의 범 위 는 0 < = Ci < = 10, 000 이다.이상 한 운영 전략 으로 인해 모든 항로 의 Ci 는 마이너스 일 수 있 습 니 다. 즉, - 10, 000 < = Ci < = 10, 000 입 니 다.
모든 도 로 는 양 방향 이 고 정방 향 과 역방향 의 비용 은 똑 같 으 며 모두 마이너스 이다.
모든 항 로 는 입력 한 아이 와 비 에 따라 아이 - > 비의 일방 통행 을 한다.실제로 지금 아이 에서 비 로 가 는 항로 가 있다 면 비 에서 아이 로 가 는 통행 방안 이 없 을 것 이라는 뜻 이다.
농부 존 은 그의 좋 은 우 유 를 배 송 센터 에서 각 도시 로 보 내 고 싶 어 합 니 다. 물론 대가 가 적 을 수록 좋 기 를 바 랍 니 다. 당신 은 그 를 도와 줄 수 있 습 니까?배 송 센터 는 도시 S 중 (1 & lt; = S & gt; = T) 에 있 습 니 다.
입력 형식 입력 의 첫 줄 에는 빈 칸 으로 구 분 된 네 개의 정수 T, R, P, S 가 포함 되 어 있 습 니 다.
그 다음 에 R 행 은 도로 정 보 를 묘사 하고 줄 마다 세 개의 정 수 를 포함 하 며 각각 Ai, Bi 와 Ci 를 나타 낸다.
그 다음 에 P 행 은 항로 정 보 를 묘사 하고 줄 마다 세 개의 정 수 를 포함 하 며 각각 Ai, Bi 와 Ci 를 나타 낸다.
출력 형식 출력 T 줄 은 도시 S 에서 도시 마다 최소 비용 을 표시 하고 도착 하지 않 으 면 NO PATH 를 출력 합 니 다.샘플 입력 6, 3, 4, 1, 2, 5, 5, 6, 10, 4, 6 - 100, 1, 3 - 10 샘플 출력 NO PATH NO PATH 5 0 - 95 - 100 데이터 규모 와 약정 에 대한 20% 데이터, T < = 100, R < = 500, P < = 500;
30% 의 데이터 에 대해 R < = 1000, R < = 10000, P < = 3000;
100% 의 데이터 에 대해 서 는 1 & lt; = T & gt; = 25000, 1 & gt; = R & gt; = 50000, 1 & gt; = P & gt; = 50000.
이 문 제 는 언뜻 보기 에는 방향 그림 과 무 방향 그림 이 있 는 혼합 형 이다. 그러나 우 리 는 가장 짧 은 길 에서 정 권 변 에 대해 지나 갈 수 있 는 정 권 변 은 당연히 적 을 수록 좋다 는 것 을 알 수 있다. 그러나 문제 에서 마이너스 가 있 는 변 은 방향 이 있다 고 말 했다. 즉, 한 번 만 지나 갈 수 있다 는 것 이다 (마이너스 링 상황 제외). 이것 은 Bellman - ford 알고리즘 만 사용 할 수 있다.이 알고리즘 은 이전에 말 한 적 이 있 는데 최적화 라 고 하 는데 SPFA 알고리즘 이 라 고 하 는데 이 최적화 에 대해 자세히 설명 하지 않 았 습 니 다. 이번 에는 이 알고리즘 으로 이 문 제 를 해결 하 더 라 도
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
public class Main
{
static int INF=100000*100000+1;
public static void main(String[] args)
{
Scanner sc=new Scanner(System.in);
int T=sc.nextInt();
int R=sc.nextInt();
int P=sc.nextInt();
int S=sc.nextInt();//
ArrayList list[]=new ArrayList[T+1];//
int x,y,w;
for(int i=0;iif(list[x]==null)list[x]=new ArrayList<>();
if(list[y]==null)list[y]=new ArrayList<>();
list[x].add(new Edge(y,w));
list[y].add(new Edge(x,w));//
}
for(int i=0;iif(list[x]==null)list[x]=new ArrayList<>();
list[x].add(new Edge(y,w));// ,
}
int d[]=new int[T+1];// S
boolean inQ[]=new boolean[T+1];// , true
for(int i=1;i<=T;i++)d[i]=INF;//
d[S]=0;// 0
inQ[S]=true;//
Queue queue=new LinkedList<>();
queue.add(S);
while(!queue.isEmpty())
{
int s=queue.poll();//
inQ[s]=false;//
if(list[s]==null)continue;// , ArrayList , ,
for(int i=0;i<list[s].size();i++)
{
Edge e=list[s].get(i);// s
if(d[s]d[s]+e.w)//
{
d[e.to]=d[s]+e.w;
if(!inQ[e.to])// , ,,
{
queue.add(e.to);
inQ[e.to]=true;
}
}
}
}
for(int i=1;i<=T;i++)
{
if(d[i]==INF)// ,
System.out.println("NO PATH");
else
System.out.println(d[i]);
}
}
}
class Edge//
{
int to,w;
Edge(int to,int w)
{
this.to=to;
this.w=w;
}
}
이 알고리즘 에 대해 우 리 는 이렇게 이해 할 수 있 습 니 다. 느슨 한 조작 을 거 친 점 을 대열 에 넣 어야 하 는 이 유 는 이 점 의 업데이트 가 후속 점 의 최 단 로 업데이트 에 영향 을 줄 수 있 기 때 문 입 니 다. 모든 점 에 최 단 로 가 존재 하거나 도달 하지 못 한다 고 가정 하면 몇 차례 의 순환 을 거 쳐 느슨 한 조작 은 다시 발생 하지 않 을 것 입 니 다. 따라서...더 이상 입단 할 경 우 는 없 을 것 이 며, 대열 은 결국 비어 있 을 것 이다. 왜냐하면 제목 이 요구 하기 때문에 마이너스 고리 가 없 을 것 이다.만약 에 네 거 티 브 링 이 있다 면 일부 점 의 업데이트 작업 은 계속 진행 되 고 무한 한 작은 추 세 를 보 이 며 순환 이 생 길 것 입 니 다. 대기 열 이 비어 있 지 않 기 때 문 입 니 다. 이런 상황 에 대한 조사 에 있어 서 우 리 는 배열 update [T + 1] 를 설정 하여 한 점 의 업데이트 횟수 를 기록 할 수 있 습 니 다. 예 를 들 어 한 점 의 업데이트 횟수 가 T - 1 회 를 초과 하면 이 그림 에 네 거 티 브 링 이 존재 한 다 는 것 을 설명 합 니 다.이로써 절 차 를 중지 하 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
[데이터 구조의 정렬 2] 정렬 을 직접 삽입 합 니 다.보통 하나의 기록 R [i] (i = 2, 3,..., n - 1) 을 현재 의 질서 구역 에 삽입 하여 삽입 한 후에 도 이 구간 의 기록 을 키워드 에 따라 질서 있 게 조작 하 는 것 을 i - 1 번 직접 삽...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.