hdu 2433 travel

今天做了一道hdu的单源最短路径问题,其问一个图中所有节点最短路径和以及删去某条边后相应的最短路径和。直接计算会超时,所以要适当记录路径,当删去的边不在某个顶点的最短路中的时候才再跑一遍bfs。相应的注意记录和计算即可。之前是将所有边的最短路径记录到了一起,导致不能很好的复用,将其分开记录才能很好的发挥预处理的作用,算是学习到一点数据结构处理的思路(不过说真的,有时候感觉我数据结构那里才是学的最差的一部分)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <assert.h>
using namespace std;
#define MAXN 101
#define INF 0x3f3f3f3f
typedef struct edge {
	int fromCity;
	int toCity;
	int weight;
	bool isValid;
	struct edge(int v, int w) { toCity = v; weight = w; isValid = true; }
	struct edge(int u, int v, int w) { fromCity = u; toCity = v; weight = w; isValid = true; }
	bool operator != (const struct edge & v) { 
		if (fromCity == v.fromCity&&toCity == v.toCity&&isValid==v.isValid)
			return false;
		else if (fromCity == v.toCity&&toCity == v.fromCity&&isValid==v.isValid)
			return false;
		return true;
	}
}Edge;
typedef int Vertex;//restore their ancestors
bool operator < (const Edge &a, const Edge &b)
{
	return a.fromCity<b.fromCity||(a.fromCity==b.fromCity&&a.toCity < b.toCity);
}
vector<Vertex > vertices;
vector<Vertex > verticesPi;
bool verticesInArray[MAXN];
vector<Edge > solvingEdges[MAXN];
vector<Edge > edgeList;
set<Edge> shortestPathEdges[MAXN];
int dijkstraWeight[MAXN];
int dijkstraWeightCopy[MAXN];
int sum;
int N, M;
void init()
{
	edgeList.clear();
	for (int i = 0; i < N; i++)
		solvingEdges[i].clear();
	for(int i=0;i<N;i++)
		shortestPathEdges[i].clear();
}
void input()
{
	int city1, city2;
	for (int i = 0; i < M; i++) {
		scanf("%d %d", &city1, &city2);
		solvingEdges[city1 - 1].push_back(Edge(city1 - 1, city2 - 1, 1));
		solvingEdges[city2 - 1].push_back(Edge(city2 - 1, city1 - 1, 1));
		edgeList.push_back(Edge(city1 - 1, city2 - 1, 1));
	}
}
void bfs(int s)
{
	for (int i = 0; i < N; i++) {
		vertices[i] = INF;
		verticesPi[i] = -1;
		verticesInArray[i] = false;
	}
	vertices[s] = 0;
	verticesPi[s] = -1;
	queue<int > bfsQueue;
	bfsQueue.push(s);
	while (bfsQueue.empty() == false) {
		int u = bfsQueue.front();
		bfsQueue.pop();
		for (int i = 0; i < solvingEdges[u].size(); i++) {
			if (solvingEdges[u][i].isValid) {
				int v = solvingEdges[u][i].toCity;
				if (verticesInArray[v] == false) {
					verticesInArray[v] = true;
					vertices[v] = vertices[u] + 1;
					verticesPi[v] = u;
					bfsQueue.push(v);
				}
			}
		}
		verticesInArray[u] = true;
	}
}
void dijkstraForOneVertex(int s, Edge disappearEdge)
{
	vertices.clear();
	for (int i = 0; i < N; i++)
		vertices.push_back(INF);
	vertices[s] = 0;
	dijkstraWeight[s] = 0;
	verticesPi.clear();
	for (int i = 0; i < N; i++)
		verticesPi.push_back(-1);
	int u = disappearEdge.fromCity;
	int v = disappearEdge.toCity;
	int k, l;
	bool set = false;
	for (k = 0; k < solvingEdges[u].size(); k++) {
		if (solvingEdges[u][k].toCity == v) {
			solvingEdges[u][k].isValid = false;
			set = true;
			break;
		}
	}
	for (l = 0; l < solvingEdges[v].size(); l++) {
		if (solvingEdges[v][l].toCity == u) {
			solvingEdges[v][l].isValid = false;
			break;
		}
	}
	bfs(s);
	if (set) {
		solvingEdges[v][l].isValid = true;
		solvingEdges[u][k].isValid = true;
	}
	sum = 0;
	for (int i = 0; i < N; i++) {
		if (vertices[i] >= INF) {
			sum = INF;
			break;
		}
		sum += vertices[i];
	}
	dijkstraWeight[s] = sum;
}
vector<int > tempo;
void getShortestEdges(int i, int j)
{
	if (i == j)
		tempo.push_back(i);
	else if (verticesPi[j] == i) {
		tempo.push_back(i);
		tempo.push_back(j);
	}
	else if (verticesPi[j] < 0)
		return;
	else {
		getShortestEdges(i, verticesPi[j]);
		tempo.push_back(j);
	}
}
void addShortestEdges(int s)
{
	for (int i = 0; i < N; i++) {
		if (i != s) {
			tempo.clear();
			getShortestEdges(s, i);
			for (int j = 0; j < tempo.size() - 1; j++) {
				shortestPathEdges[s].insert(Edge(tempo[j], tempo[j + 1], 1));
				shortestPathEdges[s].insert(Edge(tempo[j + 1], tempo[j], 1));
			}
		}
	}
}
int getSum()
{
	int ret = 0;
	for (int i = 0; i < N; i++)
		ret += dijkstraWeight[i];
	return ret;
}
void solve()
{
	memset(dijkstraWeight, 0, sizeof(dijkstraWeight));
	sum = 0;
	dijkstraForOneVertex(0, Edge(0,-1, -1));
	for(int i=0;i<N;i++)
		if (dijkstraWeight[i] >= INF) {
			for(int j=0;j<M;j++)
				printf("INF\n");//unconnected
			return;
		}
	addShortestEdges(0);
	for (int i = 1; i < N; i++) {
		dijkstraForOneVertex(i, Edge(0, -1,-1));
		addShortestEdges(i);
	}
	for (int i = 0; i < N; i++)
		dijkstraWeightCopy[i] = dijkstraWeight[i];
	set<Edge >::iterator it;
	int presentSum = getSum();
	for (int i = 0; i < edgeList.size(); i++) {
		for (int j = 0; j < N; j++)
			dijkstraWeight[j] = dijkstraWeightCopy[j];
		bool appeared = false;
		for (int j = 0; j < N; j++) {
			it = shortestPathEdges[j].find(edgeList[i]);
			if (it != shortestPathEdges[j].end()) {
				appeared = true;
				break;
			}
		}
		if (!appeared) {
			printf("%d\n", presentSum);
			continue;
		}
		else {
			bool isInf = false;
			for (int j = 0; j < N; j++) {
				it = shortestPathEdges[j].find(edgeList[i]);
				if (it == shortestPathEdges[j].end())
					continue;
				dijkstraForOneVertex(j, Edge(it->fromCity,it->toCity,it->weight));
				for (int k = 0; k < N; k++) {
					if (dijkstraWeight[k] >= INF) {
						isInf = true;
						break;
					}
				}
				if (isInf) {
					printf("INF\n");
					break;
				}
			}
			if (!isInf)
				printf("%d\n", getSum());
		}
	}
}
int main()
{
	while (scanf("%d %d", &N, &M) != EOF) {
		init();
		input();
		solve();
	}
	return 0;
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值