HDU 3499 Flight(分层图最短路)

 

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3499

       题意是有n个城市,m条路线,然后有一张半价票,问从起点到终点的最小花费。

       这道题如果不知道分层图的话很容易会想到一种错误的解法,就是跑一遍最短路,然后将最大的权值/2,可以自己试着造几个样例试试这样是不对的(比如最短路相同,但是路径不同的情况),所以这道题用分层图去跑,因为只有一张半价票,所以只需要建两层图就好了。因为如果可以到达终点的话,这张半价票肯定是要用的,所以最终的结果就一定是ma[s]到ma[t] + n,至于建图的过程看代码自己理解吧。(用的是链式前向星存图方式,所以对于边数应该是题目要求的3倍)


AC代码:

#include 
#define maxn 100005 << 1
#define maxm 500005 << 2
#define ll long long
const ll inf = 0x3f3f3f3f3f3f3f3f;
using namespace std;
struct Node{
	int to, next, w;
	bool operator < (const Node &a) const{
		return a.w < w;
	}
}Edge[maxm], Now, Next;
int head[maxn],num;
ll dist[maxn];
bool vis[maxn];
int n,m;

void init(){
	for(int i=0;i<=n*2;i++) head[i] = -1;
	num = 0;
}

void add(int u,int v,int w){
	Edge[num].to = v;
	Edge[num].w = w;
	Edge[num].next = head[u];
	head[u] = num ++;
}

void dijkstra(int s){
	for(int i=0;i<=2*n;i++){
		dist[i] = inf;
		vis[i] = false;
	}
	dist[s] = 0;
	priority_queue q;
	Now.to = s;
	q.push(Now);
	while(!q.empty()){
		int u = q.top().to;
		q.pop();
		if(vis[u]) continue;
		vis[u] = true;
		for(int i=head[u];i!=-1;i=Edge[i].next){
			int v = Edge[i].to;
			if(!vis[v] && dist[v] > dist[u] + Edge[i].w){
				dist[v] = dist[u] + Edge[i].w;
				Next.to = v;
				Next.w = dist[v];
				q.push(Next);
			}
		}
	}
}

int main()
{
	while(~scanf("%d%d",&n,&m)){
		init();
		map ma;
		int pos = 1;
		int w;
		char u[15],v[15],s[15],t[15];
		for(int i=0;i

 

你可能感兴趣的:(ACM_最短路)