您的位置:首页 > 其它

pku3169 差分约束系统

2010-07-22 12:13 267 查看
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
== INF,来判断,因为开始就是赋值的是INF
否者,返回dis
,这里面存的就是起点到终点的最大距离
*/
/*模块三*/
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
== INF){
return -2;
}
return dis
;
}
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: