【POJ3268】 실버 카우 파티 (dij / matrix transpose)

실버 카우 파티

시간 제한 : 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;
}

추천

출처blog.csdn.net/thesprit/article/details/51996659