http://acm.pku.edu.cn/JudgeOnline/problem?id=1122

http://acm.pku.edu.cn/JudgeOnline/images/1122/1122_1.gif

Код:
#include <vector>
#include <fstream>
#include <string>
#include <algorithm>
#include <iostream>
#include <stdio.h>

using namespace std;


typedef vector <int> intVec;
typedef vector <intVec> colVec;

#define min(x,y)(x < y)? x :y

struct s_path	// Shortest path
{
	int origin;
	int dest;
	string path;
	int distance;
};


typedef vector <s_path> sortableVec;

void copyVec(colVec& inVec, colVec& outVec);
void getShortestPath(string& str, colVec& vec, int src, int dest);
void printList(ostream& outFile, sortableVec& myList);
void replaceNegative(colVec& inVec);
bool comparePath(const s_path& path1, const s_path& path2);

const int INFINITE = 10000;

int main()
{	

	int size, value;
	int oneDest;	
	
	//if(cin.is_open() && cout.is_open()){
	if(cin && cout){

// Test input to vectors
cin >> size;	// Read the N value
// Four containers one pair each for result as well as trace
// matrix - we need to keep a predecessor matrix hence a pair
colVec inPre(size);
colVec inCur(size);
colVec trPre(size);
colVec trCur(size);

// Storage for fire station locations
intVec origins(size);

// Read input values
for (int i = 0; i < size; i++){
	// Create inner vectors of integers for the 4 containers
	inPre[i] = *(new intVec(size));
	inCur[i] = *(new intVec(size));
	
	trPre[i] = *(new intVec(size));
	trCur[i] = *(new intVec(size));
            for(int j =0; j < size; j++){
cin >> value;
inPre[i][j] = value;
            }
	
}
// Read the single destination
cin >> oneDest;
// Read the multiple origins and keep the count of origins
int value;
cin >> value;
int orignCount =1;
for (int i = 0;!cin.eof(); i++,orignCount++){
	origins[i] = value;
	cin >> value;
}
orignCount--; // Account for eof

replaceNegative(inPre);
copyVec(inPre,inCur);

//cin.close();

// Initialize the TraceMatrix
for(int i = 0; i < size; i++){
	for(int j = 0; j < size; j++){
if(i == j || inPre[i][j] == INFINITE){
	trPre[i][j] = INFINITE;
}
else{
	trPre[i][j] = i;
}
	} 
}

// Use floyd's for all pairs shortest path
// Make a result array as well as trace array
int trace = 0;
for(int k = 0; k < size; k++){
	for(int i = 0; i < size; i++){
for(int j =0; j < size; j++){
	inCur[i][j] = (min(inCur[i][j], inCur[i][k] + inCur[k][j]));
	trCur[i][j] = (inPre[i][j] <= inPre[i][k]  + inPre[k][j])?
trPre[i][j] : trPre[k][j];
	
}
	}
	// Swap input matrix keeping as predecessor matrix
	copyVec(inCur, inPre);
	// Swap trace matrix for keeping as predecessor matrix
	copyVec(trCur, trPre);
}
// Find the path and insert the result into a sortableVector
// before printing
sortableVec myList;
for(int i = 0; i < orignCount; i++){
	s_path* fs_path= new s_path;
	fs_path->origin= origins[i];
	fs_path->dest= oneDest;
	fs_path->distance	= inCur[origins[i] -1][oneDest-1];

	getShortestPath(fs_path->path, trCur, fs_path->origin -1,
oneDest-1);
	
	// Insert this path to the list for sorting
	myList.push_back(*fs_path);

}
// Sort the list
sort(myList.begin(), myList.end(), comparePath);
// Print the List
printList(cout,myList);
//cout.close();
	}
	return 0;
}

// Copy the inVec elements to the outVec 
void copyVec(colVec& inVec, colVec& outVec)
{
	int size = inVec.size();
	for(int i = 0; i < size; i++){
for(int j =0; j < size; j++){
	outVec[i][j] = inVec[i][j];
}
	}
}

// Replace -1 with a large +ve value
void replaceNegative(colVec& inVec)
{
	int size = inVec.size();
	for(int i = 0; i < size; i++){
for(int j =0; j < size; j++){
	if(inVec[i][j] == -1){
inVec[i][j] = INFINITE;
	}
}
	}
}


// Get the shortest path from the trace matrix
void getShortestPath(string& str, colVec& traceMat, int src, int dest)
{
	char* buff = new char[80];
	if (src == dest){
	        //_itoa(src + 1, buff, 10);
 	        sprintf(buff, "%i", src + 1);
str += buff;
	}
	else if(traceMat[src][dest] == INFINITE){
//str << "No path from " << src <<" to " << dest;
	}
	else{
getShortestPath(str, traceMat, src, traceMat[src][dest]);
str += '\t';
//_itoa(dest + 1, buff, 10);
 	        sprintf(buff, "%i", dest + 1);
str += buff;
	}
}

// Print the sorted paths from the map
void printList(ostream& outFile, sortableVec& myList)
{
	// Print the map
	sortableVec::iterator it; 
	outFile << "Org\tDest\tTime\tPath\n";
	for (it = myList.begin(); it != myList.end(); it++){
s_path* myPath = &(*it);

outFile  << myPath->origin<<'\t'
 << myPath->dest<<"\t"
 << myPath->distance<<"\t"
 << myPath->path<<'\n';
	}
}

	
//Compare Function
bool comparePath(const s_path& path1, const s_path& path2)
{	
	if(path1.distance < path2.distance){
return true;	
	}
	else{
return false;
	}
}