【最短路+dijkstra】杭电 hdu 2923 Einbahnstrasse

 

/* THE PROGRAM IS MADE BY PYY */
/*----------------------------------------------------------------------------//
	Copyright (c) 2011 panyanyany All rights reserved.

	URL   : http://acm.hdu.edu.cn/showproblem.php?pid=2923
	Name  : 2923 Einbahnstrasse

	Date  : Wednesday, January 18, 2012
	Time Stage : two hours

	Result: 
5272119	2012-01-18 15:32:10	Accepted	2923
62MS	300K	2686 B
C++	pyy


Test Data :

Review :
一次AC, 太神奇了~~
//----------------------------------------------------------------------------*/

#include <stdio.h>
#include <string>
#include <map>
#include <utility>
#include <iostream>

using namespace std ;

#define INF		0x3f3f3f3f
#define MAXN	105

#define min(x, y)	((x) < (y) ? (x) : (y))
#define MEM(a, v)	memset (a, v, sizeof (a))


bool	used[MAXN] ;

int		n, c, r, iCityCnt ;
int		graph[MAXN][MAXN], cars[MAXN], from[MAXN], to[MAXN] ;

void dijkstra (int * dist, bool bfrom)
{
	int i, j ;
	int iMinPath, MinPath ;
	
	MEM(used, 0) ;
	
	for (i = 1 ; i <= n ; ++i)
	{
		dist[i] = (bfrom ? graph[1][i] : graph[i][1]) ;
	}
	
	for (i = 1 ; i <= n ; ++i)
	{
		iMinPath = 0 ; 
		MinPath = INF ;
		for (j = 1 ; j <= n ; ++j)
		{
			if (!used[j] && dist[j] < MinPath)
			{
				iMinPath = j ;
				MinPath = dist[j] ;
			}
		}
		
		used[iMinPath] = 1 ;
		
		for (j = 1 ; j <= n ; ++j)
			if (!used[j])
				dist[j] = min (dist[j], dist[iMinPath] + 
				(bfrom ? graph[iMinPath][j] : graph[j][iMinPath])) ;
	}
}

template <typename T>
void addCity (T &cnr, string city)
{
	pair<typename T::iterator, bool> ret ;
	ret = cnr.insert (pair<string, int> (city, iCityCnt)) ;
	iCityCnt += (ret.second ? 1 : 0) ;	// 
}

int main ()
{
	int i, j, k ;
	int v, sum, tcase ;
	string str ;
	char	stra[20], strb[20], ca, cb ;
	
	tcase = 0 ;
	while (scanf ("%d%d%d", &n, &c, &r), n | c | r)
	{
		MEM(graph, INF) ;
		MEM(cars, 0) ;

		map<string, int>	id ;

		// number each location
		for (i = iCityCnt = 1 ; i <= c + 1 ; ++i)
		{
			cin >> str ;
			// 各点的处理比较别扭,因为它们不是一次性给出的,而是分两部分给的
			// 第一部分出现在汽车出事的点,这里给出的点仅仅是一部分而已
			addCity (id, str) ;
			++cars[id[str]] ;
		}
		for (i = 1 ; i <= r ; ++i)
		{
			scanf ("%s %c-%d-%c %s", stra, &ca, &v, &cb, strb) ;
			// 这里也给出了各点,而且这里给出的才是完整的。但在我的程序里,
			// 优先选择前面的点,剩下的点在这里补充
			addCity (id, string (stra)) ;
			addCity (id, string (strb)) ;
			j = id[stra] ;
			k = id[strb] ;
			// 根据路径的方向给地图加边
			if (ca == '<')
				graph[k][j] = min (graph[k][j], v) ;
			if (cb == '>')
				graph[j][k] = min (graph[j][k], v) ;
		}

		// 因为要求拖车从总站出发,然后把车拖回总站,所以一来一回就有两段路
		// 所以第一次 dijkstra 就计算从总站到各点的路径
		// 第二次 dijkstra 就计算从各点到总站的路径
		dijkstra (from, 1) ;
		dijkstra (to, 0) ;
		
		sum = 0 ;
		for (i = 2 ; i <= n ; ++i)
		{
			// 有几辆车,该路就要走几次
			if (from[i] < INF)
				sum += from[i] * cars[i] ;
			if (to[i] < INF)
				sum += to[i] * cars[i] ;
		}
		printf ("%d. %d\n", ++tcase, sum) ;
	}
	return 0 ;
}

 

你可能感兴趣的:(ACM,图论,最短路,dijkstra)