URAL 1416 Confidential

#include <stdio.h>

#define INF (1 << 31 - 1)
#define MAX_PLANETS 501

int numOfPlanets;
int numOfPassages;
int costArray[MAX_PLANETS][MAX_PLANETS];

int minCostArray[MAX_PLANETS];
int added[MAX_PLANETS];

int planetAddBy[MAX_PLANETS];
int totalCost;
int stack[MAX_PLANETS];
int top;
int maxCostArray[MAX_PLANETS][MAX_PLANETS];//maxCostArray[i][j]来表示MST中从i到j经过的最大边权 PS:中途可能经过多个边
int noMST;

int main(){
	//freopen("input.txt", "r", stdin);
	/* input */
	scanf("%d %d", &numOfPlanets, &numOfPassages);
	//reset 
	int from, to;
	for (from = 1; from <= numOfPlanets; from++){
		minCostArray[from] = INF;
		planetAddBy[from] = 1;
		for (to = from + 1; to <= numOfPlanets; to++){
			costArray[from][to] = INF;
			costArray[to][from] = INF;
		}
	}
	int indexOfPassage;
	for (indexOfPassage = 1; indexOfPassage <= numOfPassages; indexOfPassage++){
		int from, to, cost;
		scanf("%d %d %d", &from, &to, &cost);
		costArray[from][to] = cost;
		costArray[to][from] = cost;
	}

	/*  minimum spanning tree Prim algorithm */
	//initial minCostrArray
	int indexOfPlanet;
	for (indexOfPlanet = 2; indexOfPlanet <= numOfPlanets; indexOfPlanet++){
		minCostArray[indexOfPlanet] = costArray[1][indexOfPlanet];
	}
	minCostArray[1] = 0;
	added[1] = 1;
	top++;
	stack[top] = 1;
	//main loop
	int numOfPlanetsAdded;
	for (numOfPlanetsAdded = 2; numOfPlanetsAdded <= numOfPlanets; numOfPlanetsAdded++){
		//to find min cost in minCostrArray
		int minCost = INF;
		int minCostPlanet = 1;
		for (indexOfPlanet = 2; indexOfPlanet <= numOfPlanets; indexOfPlanet++){
			if (added[indexOfPlanet] == 0 && minCostArray[indexOfPlanet] < minCost){
				minCost = minCostArray[indexOfPlanet];
				minCostPlanet = indexOfPlanet;
			}
		}
		if (minCost == INF){
			noMST = 1;
			break;
		}
		//add minCostPlanet into MST
		added[minCostPlanet] = 1;
		totalCost += minCost;
		top++;
		stack[top] = minCostPlanet;
		//update maxCostArray
		int index;
		for (index = 1; index < top; index++){
			int planetAdded = stack[index];		
			int maxCost = maxCostArray[ planetAddBy[minCostPlanet] ] [planetAdded];
			if (minCost > maxCost){
				maxCostArray[minCostPlanet][planetAdded] = minCost;
				maxCostArray[planetAdded][minCostPlanet] = minCost;
			} else {
				maxCostArray[minCostPlanet][planetAdded] = maxCost;
				maxCostArray[planetAdded][minCostPlanet] = maxCost;
			}
		}	
		//update minCostrArray
		for (indexOfPlanet = 2; indexOfPlanet <= numOfPlanets; indexOfPlanet++){
			if (added[indexOfPlanet] == 0 && costArray[indexOfPlanet][minCostPlanet] < minCostArray[indexOfPlanet]){
				minCostArray[indexOfPlanet] = costArray[indexOfPlanet][minCostPlanet];
				planetAddBy[indexOfPlanet] = minCostPlanet;//记录indexOfPlanet是通过minCostPlanet跟新与MST的距离
			}
		}
	}

	/* output */
	if (noMST){
		printf("Cost: -1\nCost: -1");
		return 0;
	}
	printf("Cost: %d\n", totalCost);
	int nextTotalCost = INF;
	for (from = 1; from <= numOfPlanets; from++){
		for (to = from + 1; to <= numOfPlanets; to++){
			if (costArray[from][to] != INF && planetAddBy[from] != to && planetAddBy[to] != from){
				//加入一条不在MST中的边costArray[from][to],减去maxCostArray[from][to]
				int newTotalCost = totalCost + costArray[from][to] - maxCostArray[from][to];
				if (newTotalCost < nextTotalCost){
					nextTotalCost = newTotalCost;
				}
			}
		}
	}
	if (nextTotalCost == INF){
		printf("Cost: -1");
	} else {
		printf("Cost: %d", nextTotalCost);
	}
	return 0;
}

你可能感兴趣的:(confidential,ural,1416)