실버 카우 파티
시간 제한 : 2000ms 메모리 제한 : 65536KB 64 비트 정수 IO 형식 : % lld Java 클래스 이름 : Main
N 개의 농장 (1 ≤ N ≤ 1000) 각각에서 1 마리씩 편리하게 번호가 1..N은 농장 #X (1 ≤ X ≤ N)에서 열리는 큰 젖소 파티에 참석할 예정입니다. 총 M (1 ≤ M ≤ 100,000)의 단방향 (일방 통행 도로는 농장 쌍을 연결하고, 도로 i는 횡단하는 데 Ti (1 ≤ Ti ≤ 100) 단위 시간이 필요합니다.
각 소는 파티로 걸어 가야하며 파티가 끝나면 농장으로 돌아 가야합니다. 각 젖소는 게으 르기 때문에 가장 짧은 시간에 최적의 경로를 선택합니다. 길은 일방 통행이기 때문에 젖소의 반환 경로는 원래 파티로가는 경로와 다를 수 있습니다.
모든 젖소 중에서 젖소가 파티에 갔다가 돌아 오는 데 보내는 가장 긴 시간은 얼마입니까?
입력
1 행 : 공백으로 구분 된 3 개의 정수 : 각각 N, M 및 X 2
행. M + 1 : i + 1 행은 Ai, Bi 및 Ti의 3 개의 공백으로 분리 된 정수로 도로 i를 설명합니다. 설명 된 도로는 농장 Ai에서 농장 Bi까지 이어지며, Ti 시간 단위가 횡단해야합니다.
산출
1 행 : 정수 1 개 : 소 한 마리가 걸어야하는 최대 시간.
샘플 입력
8 4 2
1 2 4
1 3 2
1 4 7
2 1 1
2 3 5
3 1 2
3 4 4
4 2 3
샘플 출력
10
주제의 주요 아이디어 : 오래된 암소에는 파티가 있고 각 암소는 외양간에 산다 (1 ~ n). 모든 젖소 중에서 오래된 젖소를 오가는 가장 긴 여정을 찾아달라고 요청하십시오 (소 도둑 JB는 게으르지 만 매우 영리하며 가거나 올 것인지 가장 짧은 경로입니다). 점의 수, 변의 수, 늙은 젖소의 위치를 나타내는 세 개의 숫자를 입력합니다. 이것은 유 방향 그래프 map[a][b]不一定等于map[b][a]
입니다.
분석 : 처음에는 DIJ의 아이디어에 따라 오래된 젖소의 위치 X에서 시작하여 다른 지점으로가는 최단 경로를 찾습니다. 그런 다음 인접 행렬을 전치하고 (맵 [] [] 전치) X에서 DIJ를 다시 시작하고 다른 지점에서 X까지의 최단 경로를 찾습니다. 가장 큰 경로를 얻기 위해 최단 경로를 기록하는 두 개의 배열을 추가하면 완료됩니다.
#include "iostream"
#include "cstdio"
#include "cstring"
#include "algorithm"
using namespace std;
const int maxn = 1e3+5;
const int INF = 0x3f3f3f3f;
int map[maxn][maxn];
int dis[maxn];
int vis[maxn];
int dd[maxn];
int n,m,x;
int a,b,time;
void dij(){
memset(vis,0,sizeof(vis));
memset(dis,INF,sizeof(dis));
dis[x]=0;
for( int i=1 ; i<=n ; i++ ){
int u = -1;
for( int j=1 ; j<=n ; j++ ){
if(!vis[j]&&(u==-1||dis[j]<dis[u])){
u=j;
}
}
vis[u]=1;
for( int j=1 ; j<=n ; j++ ){
if(dis[j]>dis[u]+map[u][j]){
dis[j] = dis[u] + map[u][j];
}
}
}
}
int main(){
while(~scanf("%d%d%d",&n,&m,&x)){
memset(map,INF,sizeof(map));
while(m--){
scanf("%d%d%d",&a,&b,&time);
map[a][b]=time;
}
dij();
for( int i=1 ; i<=n ; i++ ){
dd[i]=dis[i];
}
for( int i=1 ; i<=n ; i++ ){
for( int j=i+1 ; j<=n ; j++ ){
map[i][j] = map[i][j] ^ map[j][i];
map[j][i] = map[i][j] ^ map[j][i];
map[i][j] = map[i][j] ^ map[j][i];
}
}
dij();
int max=-1;
for( int i=1 ; i<=n ; i++ ){
if((dd[i]+dis[i])>max){
max = dd[i]+dis[i];
}
}
printf("%d\n",max);
}
return 0;
}