Layout

这题还是用的 SPFA + 栈 过的,400多ms,写得多了,发现都可以套用模块了,除了输入不太一样外,其他的都基本一样。

模块一:负责各个数组的初始化

模块二:负责加边,对边用邻接表处理

模块三:SPFA 用栈来实现的过程

代码
#include<stdio.h>
#include
<stdlib.h>
#define INF 0xfffffff
#define NN 1004
#define MM 20004

int edNum, N;
int next[MM];
int root[NN];
int mark[NN];
int cnt[NN];
int dis[NN];
int stack[NN];

struct node{
int e, v;
}edge[MM];

/*在这里我用了一个函数来完成初始化,也可以看着一个固定模块了*/
/*模块一*/
void Init(){
int i;
for (i = 0; i <= N; i++){
root[i]
= -1;
mark[i]
= 0;
cnt[i]
= 0;
}
}
/*模块二*/
void add(int a, int b, int c){
edge[edNum].e
= b;
edge[edNum].v
= c;
next[edNum]
= root[a];
root[a]
= edNum++;
}
/*函数返回-1,表示有负边权回路,就表示不可能
函数返回-2,就表示起点到终点的距离不定,这里用dis[N] == INF,来判断,因为开始就是赋值的是INF
否者,返回dis[N],这里面存的就是起点到终点的最大距离
*/
/*模块三*/
int Spfa()
{
int i, top, cur, tmp, nxt;
top
= 0;
for (i = 1; i <= N; i++){
dis[i]
= INF;
if (root[i] != -1){
stack[
++top] = i;
cnt[i]
++;
mark[i]
= 1;
}
}
dis[
1] = 0;

while (top){
cur
= stack[top--];
tmp
= root[cur];
mark[cur]
= 0;
while (tmp != -1){
nxt
= edge[tmp].e;
if (dis[nxt] > dis[cur] + edge[tmp].v){
dis[nxt]
= dis[cur] + edge[tmp].v;
if (!mark[nxt]){
cnt[nxt]
++;
if (cnt[nxt] > N + 1){
return -1;
}
mark[nxt]
= 1;
stack[
++top] = nxt;
}
}
tmp
= next[tmp];
}
}
if (dis[N] == INF){
return -2;
}
return dis[N];
}
int main()
{
int ML, MD, a, b, c;
scanf(
"%d%d%d", &N, &ML, &MD);
Init();
while (ML--){
scanf(
"%d%d%d", &a, &b, &c);
add(a, b, c);
}
while (MD--){
scanf(
"%d%d%d", &a, &b, &c);
add(b, a,
-c);
}
printf(
"%d\n", Spfa());
//system("pause");
return 0;
}

 

posted on 2010-07-22 12:13  ylfdrib  阅读(225)  评论(0编辑  收藏  举报