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

Код:
#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;
}
}