#include <stdio.h>
#define MAX_CITIES 555
#define MAX_AGREEMENTS (MAX_CITIES * MAX_CITIES)
#define INF (1 << 30)
#define QUEUE_SIZE 200000000
int numOfCities;
int numOfAgreements;
struct AGREEMENT{
int adjaCity;
int hours;
int nextAgreementNum;
};
AGREEMENT agreementNumOfAdjaList[MAX_AGREEMENTS];
int agreementNumLastAdded[MAX_CITIES];
int time;
int cityTime[MAX_CITIES];
int rootTime[MAX_CITIES];
int cityStack[MAX_CITIES];
int top;
int inStack[MAX_CITIES];
int SCCNumArray[MAX_CITIES];
int numOfSCCs;
int numOfQueries;
int origin;
int destination;
int distFromOrigin[MAX_CITIES];
int queue[QUEUE_SIZE];
int back;
int front;
int inQueue[MAX_CITIES];
int minTime;
void getSCCs(int headCity){
time++;
cityTime[headCity] = time;
rootTime[headCity] = time;
top++;
cityStack[top] = headCity;
inStack[headCity] = 1;
int agreementNum;
for (agreementNum = agreementNumLastAdded[headCity]; agreementNum != 0; agreementNum = agreementNumOfAdjaList[agreementNum].nextAgreementNum){
int adjaCity = agreementNumOfAdjaList[agreementNum].adjaCity;
int hours = agreementNumOfAdjaList[agreementNum].hours;
if (cityTime[adjaCity] == 0){
getSCCs(adjaCity);
if (rootTime[adjaCity] < rootTime[headCity]){
rootTime[headCity] = rootTime[adjaCity];
}
} else {
if (inStack[adjaCity] == 1 && cityTime[adjaCity] < rootTime[headCity]){
rootTime[headCity] = cityTime[adjaCity];
}
}
}
if (cityTime[headCity] == rootTime[headCity]){
numOfSCCs++;
int SCCNum = numOfSCCs;
int popCity;
do {
popCity = cityStack[top];
top--;
inStack[popCity] = 0;
SCCNumArray[popCity] = SCCNum;
} while (popCity != headCity);
}
}
int queryUsingSPFA( ){
//initial
int indexOfCity;
for (indexOfCity = 1; indexOfCity <= numOfCities; indexOfCity++){
distFromOrigin[indexOfCity] = INF;
inQueue[origin] = 0;
}
distFromOrigin[origin] = 0;
front = 0;
back = 0;
queue[back] = origin;
back++;
inQueue[origin] = 1;
while (front < back){
int pop = queue[front];
front++;
inQueue[pop] = 0;
int headCity = pop;
int agreementNum;
for (agreementNum = agreementNumLastAdded[headCity]; agreementNum != 0; agreementNum = agreementNumOfAdjaList[agreementNum].nextAgreementNum){
int adjaCity = agreementNumOfAdjaList[agreementNum].adjaCity;
int hours;
if (SCCNumArray[headCity] == SCCNumArray[adjaCity]){
hours = 0;
} else {
hours = agreementNumOfAdjaList[agreementNum].hours;
}
if (distFromOrigin[headCity] + hours < distFromOrigin[adjaCity]){
distFromOrigin[adjaCity] = distFromOrigin[headCity] + hours;
if (!inQueue[adjaCity]){
int push = adjaCity;
queue[back] = push;
back++;
inQueue[push] = 1;
}
}
}
}//end of while (front < back)
return distFromOrigin[destination];
}
int main(){
//freopen("input.txt", "r", stdin);
while (1){
/* input */
scanf("%d %d", &numOfCities, &numOfAgreements);
if (numOfCities == 0 && numOfAgreements == 0){
return 0;
}
int indexOfCity;
for (indexOfCity = 1; indexOfCity <= numOfCities; indexOfCity++){
agreementNumLastAdded[indexOfCity] = 0;
}
int indexOfAgreement;
for (indexOfAgreement = 1; indexOfAgreement <= numOfAgreements; indexOfAgreement++){
int headCity;
int adjaCity;
int hours;
scanf("%d %d %d", &headCity, &adjaCity, &hours);
int agreementNum = indexOfAgreement;
agreementNumOfAdjaList[agreementNum].adjaCity = adjaCity;
agreementNumOfAdjaList[agreementNum].hours = hours;
agreementNumOfAdjaList[agreementNum].nextAgreementNum = agreementNumLastAdded[headCity];
agreementNumLastAdded[headCity] = agreementNum;
}
/* getSCCs */
time = 0;
top = 0;
for (indexOfCity = 1; indexOfCity <= numOfCities; indexOfCity++){
inStack[indexOfCity] = 0;
cityTime[indexOfCity] = 0;
}
numOfSCCs = 0;
for (indexOfCity = 1; indexOfCity <= numOfCities; indexOfCity++){
int headCity = indexOfCity;
if (cityTime[headCity] == 0){
getSCCs(headCity);
}
}
/* query */
scanf("%d", &numOfQueries);
while (numOfQueries--){
scanf("%d %d", &origin, &destination);
if (SCCNumArray[origin] == SCCNumArray[destination]){
printf("0\n");
continue;
}
minTime = queryUsingSPFA( );
//output
if (minTime == INF){
printf("Nao e possivel entregar a carta\n");
} else {
printf("%d\n", minTime);
}
}
printf("\n");
}
}
POJ 3114 Spy Communication (强连通分量tarjan + SPFA)
最新推荐文章于 2018-08-30 23:10:35 发布