Problem
Angel最近无聊,去了圣诞岛(CX *^_^*),他喜欢无目的的乱逛,当然,他不会轻易地回头。Angel想去广场,那么,他什么时候才能到呢?你已经得到了CX的地图,地图上有N(N <= 100)个交叉路口,交叉路口之间有马路相连接(不超过1000条马路)。因为CX的人遵循奇怪的规则,道路都是单向的,不同的道路之间有一定的距离,我们假设Angel所在的地点为点1,广场所在点为N。假设Angel走一单位距离需要一单位时间。问Angel最早和最迟什么时候到达广场?
Input
本题有多组数据,第一行N, M,M是边的数量以后M行,每行3个整数X, Y, Weight,代表一条从X城市到Y城市,长度为Wweight的边。
Output
每组数据,第一行是最少时间,第二行是最迟时间,要是可怜的Angel可能永远到不了广场,输出一行Never。
Sample Input
5 5
1 2 1
1 4 10
2 3 1
3 4 1
4 5 1
Sample Output
4
11
源码:
#include <assert.h>
#ifdef _DEBUG
#include <stack> //for showing path
#endif
#define MAX_N 100
#define MAX_M 1000
#define COST_IFINITE -1
int n,m;
struct _List
{
int vertex;
int cost;
_List *next;
};
struct Vertex_t
{
Vertex_t() : cost(COST_IFINITE), parent(0), isVisited(false), head(NULL), worstCost(COST_IFINITE)
{/**/}
_List *head;
int cost;
int parent;
bool isVisited;
int worstParent;
int worstCost;
};
Vertex_t vertics[MAX_N+1];
int min_cost,max_cost;
Vertex_t *min_who,*max_who;
void ReadGraph(FILE *file)
{
int i=m;
while(i-- > 0)
{
int a,b,c;
fscanf(file,"%d %d %d/n",&a,&b,&c);
_List *p = new _List;
p->vertex = b;
p->cost = c;
p->next = NULL;
if(vertics[a].head == NULL)
{
vertics[a].head = new _List;
vertics[a].head->vertex = a;
vertics[a].head->next = p;
}else
{
p->next = vertics[a].head->next;
vertics[a].head->next = p;
}
}
}
void Resolve(int toVisit,int cost,Vertex_t *who)
{
if(toVisit < 1 || toVisit > n)
return;
if(!vertics[toVisit].isVisited)
{
vertics[toVisit].isVisited = true;
vertics[toVisit].cost = who->cost + cost;
vertics[toVisit].parent = who->head->vertex;
vertics[toVisit].worstCost = who->worstCost + cost;
vertics[toVisit].worstParent = who->head->vertex;
}else
{
if(vertics[toVisit].cost > who->cost + cost)
{
vertics[toVisit].cost = who->cost + cost;
vertics[toVisit].parent = who->head->vertex;
}
if(vertics[toVisit].worstCost < who->worstCost + cost)
{
vertics[toVisit].worstCost = who->worstCost + cost;
vertics[toVisit].worstParent = who->head->vertex;
}else
return;
}
if(toVisit == n)
{
if(!min_who || cost + who->cost < min_cost)
{
min_cost = cost + who->cost;
min_who = who;
}
if(!max_who || who->worstCost + cost > max_cost)
{
max_who = who;
max_cost = who->worstCost + cost;
}
return;
}
_List *p = vertics[toVisit].head->next;
while(p)
{
Resolve(p->vertex,p->cost,&vertics[toVisit]);
p = p->next;
}
}
int main()
{
vertics[1].cost = 0;
vertics[1].worstCost = 0;
FILE *fp = fopen("data.dat","rb");
fscanf(fp,"%d %d/n",&n,&m);
ReadGraph(fp);
_List *p = vertics[1].head->next;
while(p)
{
Resolve(p->vertex,p->cost,&vertics[1]);
p = p->next;
}
if(min_who == NULL)
{
printf("Impossible!/n");
return 0;
}
printf("min %d/n",min_cost);
if(max_who == NULL)
{
printf("Impossible!/n");
return 0;
}
printf("max %d/n",max_cost);
#ifdef _DEBUG
{
Vertex_t *pv = min_who;
using std::stack;
stack<int> path;
path.push(n);
while(pv->parent)
{
path.push(pv->head->vertex);
pv = &vertics[pv->parent];
}
path.push(1);
while(path.size() != 0)
{
printf("%d ",path.top());
path.pop();
}
printf("/n");
}
{
Vertex_t *pv = max_who;
using std::stack;
stack<int> path;
path.push(n);
while(pv->worstParent)
{
path.push(pv->head->vertex);
pv = &vertics[pv->worstParent];
}
path.push(1);
while(path.size() != 0)
{
printf("%d ",path.top());
path.pop();
}
printf("/n");
}
#endif //_DEBUG
return 0;
}
//data.dat
5 5
1 2 20
1 4 10
2 3 1
3 4 20
4 5 1
//output
min 11
max 42
1 4 5
1 2 3 4 5
Press any key to continue