POJ 3114 Spy Communication (强连通分量tarjan + SPFA)

#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");	
	}	
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值