1003. Emergency
Posted chanwunsam
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了1003. Emergency相关的知识,希望对你有一定的参考价值。
这道题一开始就卡在了题目没看清这个问题上。题目是最短路径的变形,但是输出要求的最短路径的条数和路径上结点值的最大和。
#include <stdio.h>
#include <stdlib.h>
#define MaxVertexNum 500
#define INFINITY 65535 /* 二进制的2^16,即int类型最大储存值 */
typedef int ElementType;
typedef int WeightType;
typedef int Vertex;
/* 图结点 */
struct GNode{
int Nv, Ne;
WeightType G[MaxVertexNum][MaxVertexNum];
ElementType Data[MaxVertexNum];
};
typedef struct GNode *PtrToGNode;
typedef PtrToGNode MGraph;
MGraph CreateGraph(int VertexNum);
MGraph BuildGraph(int M, int N);
void Dijkstra_X(MGraph Graph, int path[], int dist[], Vertex S, Vertex E);
Vertex FindMindist(MGraph Graph, int dist[], int collected[]);
int main()
{
//freopen("C:\Users\ChanWunsam\Desktop\pat\pat_in.txt","r",stdin);
//freopen("C:\Users\ChanWunsam\Desktop\pat\pat_out.txt","w",stdout);
int M, N, C1, C2;
int dist[MaxVertexNum], path[MaxVertexNum], Sum;
MGraph Graph;
Vertex W;
scanf("%d %d %d %d", &M, &N, &C1, &C2);
Graph=BuildGraph(M, N);
if(C1==C2) /* 如果起始地和目的地相同 */
{
printf("%d %d", 1, Graph->Data[C1]);
}
else
Dijkstra_X(Graph, dist, path, C1, C2);
return 0;
}
MGraph CreateGraph(int VertexNum)
{
Vertex V, W;
MGraph Graph;
Graph=(MGraph)malloc(sizeof(struct GNode));
Graph->Nv=VertexNum;
Graph->Ne=0;
for(V=0; V<VertexNum; V++)
{
Graph->Data[V]=-1;
for(W=0; W<VertexNum; W++)
{
Graph->G[V][W]=INFINITY;
}
}
return Graph;
}
MGraph BuildGraph(int M, int N)
{
int data, i;
Vertex V, W;
WeightType Weight;
MGraph Graph;
Graph=CreateGraph(M);
Graph->Ne=N;
for(V=0; V<Graph->Nv; V++)
{
scanf("%d", &data);
Graph->Data[V]=data;
}
for(i=0; i<Graph->Ne; i++)
{
scanf("%d %d %d", &V, &W, &Weight);
/* 插入边 */
Graph->G[V][W]=Weight;
Graph->G[W][V]=Weight;
}
return Graph;
}
void Dijkstra_X(MGraph Graph, int path[], int dist[], Vertex S, Vertex E) /* 单源最短路径算法变形 */
{
/* path记录每个点的最短路径条数,dist记录每个点的最短路径长度,Sum记录每个点的最短路径上的最大救援队数量 */
int collected[MaxVertexNum], Sum[MaxVertexNum];
Vertex V, W;
/* 初始化:此处默认邻接矩阵中不存在的边用INFINITY表示 */
dist[S] = 0;
collected[S] = true;
Sum[S]=Graph->Data[S];
for ( V=0; V<Graph->Nv; V++ )
{
if(V==S)
V++;
dist[V] = Graph->G[S][V];
if ( dist[V]<INFINITY )
{
Sum[V]=Sum[S]+Graph->Data[V];
path[V] = 1;
}
else /* 如果没有路径,赋值-1,方便检查 */
{
Sum[V]=-1;
path[V] = -1;
}
collected[V] = false;
}
while (1) {
/* V = 未被收录顶点中dist最小者 */
V = FindMindist( Graph, dist, collected );
if ( V==-1 ) /* 若这样的V不存在 */
break; /* 算法结束 */
collected[V] = true; /* 收录V */
for( W=0; W<Graph->Nv; W++ ) /* 对图中的每个顶点W */
/* 若W是V的邻接点并且未被收录 */
if ( collected[W]==false && Graph->G[V][W]<INFINITY ) {
/* 若收录V使得dist[W]变小 */
if ( dist[V]+Graph->G[V][W] < dist[W] ) {
dist[W] = dist[V]+Graph->G[V][W]; /* 更新dist[W] */
path[W] = path[V];
Sum[W]=Sum[V]+Graph->Data[W];
}
else if(dist[V]+Graph->G[V][W] == dist[W]){
path[W]+=path[V];
if(Sum[V]+Graph->Data[W] > Sum[W])
Sum[W]=Sum[V]+Graph->Data[W];
}
}
} /* while结束*/
printf("%d %d", path[E], Sum[E]);
}
Vertex FindMindist(MGraph Graph, int dist[], int collected[])
{
Vertex V, MinV;
int MinDist;
MinDist=INFINITY;
for(V=0; V<Graph->Nv; V++)
{
if(!collected[V] && dist[V]<MinDist)
{
MinDist=dist[V];
MinV=V;
}
}
if(MinDist<INFINITY)
return MinV;
else
return -1;
}
实在做太久了,这周的任务铁定完不成。
最后是卡在了第二个测试点,这个测试点是起始点和目的点相同,输出会比较特殊。
需要注意的是path和Sum的更新方法,不是递加而是加上前面结点的值。
我的代码可能看起来比较方便,但是时间复杂度和空间复杂度就没那么好了,就这样吧。
以上是关于1003. Emergency的主要内容,如果未能解决你的问题,请参考以下文章