ACM学习之路——HDU2544 HDU2066(spfa)

题目链接

HDU2544  http://acm.hdu.edu.cn/showproblem.php?pid=2544

HDU2066 http://acm.hdu.edu.cn/showproblem.php?pid=2066


话说这两道我用的是spfa算法,由于第一次使用这个算法,找bug真是找的我昏天黑地。

第一个要注意的就是链式前向星的位置变量CNT在每一次的循环中都要初始化0;另外,其余的数组最好初始化为-1;以防止越界。


AC代码:

/ 
//                        HDU 2066                     //
//  Created by 吴尔立 			               //
//  Copyright (c) 2015年 吴尔立. All rights reserved.  //
/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>           
#include <algorithm>
#include <cctype>
#include <stack>
#include <queue>
#include <map>
#include <string>
#include <set>
#include <vector>
#define ll long long;
#define INF 1<<31
#define cir(i,a,b)  for (int i=a;i<=b;i++)
#define CIR(j,a,b)  for (int j=a;j>=b;j--)
#define CLR(x) memset(x,0,sizeof(x))
using namespace std;
#define maxn 2100
int pnt[maxn],nxt[maxn],head[maxn],w[maxn],cnt=0;
int T,S,D;
bool vis[maxn];
int d[maxn];

void addedge(int u,int v,int weight)
{
	pnt[cnt]=v;nxt[cnt]=head[u];head[u]=cnt;w[cnt]=weight;
	cnt++;
}

int  spfa()
{
	queue<int> q;
	memset(d,0x3f,sizeof(d));
	memset(vis,false,sizeof(vis)); 
	d[0]=0;
	q.push(0);
	vis[0]=true;
	while (!q.empty())
	{
		int x=q.front();
		q.pop();
		for (int i=head[x];~i;i=nxt[i])
		{
			int v=pnt[i];
			if (d[x]+w[i]<d[v] || d[v]==0x3f)
			{
				d[v]=d[x]+w[i];
				if (!vis[v])
				{
					q.push(v);
					vis[v]=true;
				}
			}
		}
		vis[x]=false;		
	}
	return d[1001];
}

int main()
{
	while(cin >> T >> S >> D)
	{
		cnt=0;
		memset(nxt,-1,sizeof(nxt));
		memset(head,-1,sizeof(head));
		cir (i,1,T)
		{
			int a,b,time;
			scanf("%d%d%d",&a,&b,&time);
			addedge(a,b,time);
			addedge(b,a,time);
		}
		cir(i,1,S)
		{
			int u;
			scanf("%d",&u);
			addedge(0,u,0);
			addedge(u,0,0);
		}	
		cir(i,1,D)
		{
			int v;
			scanf("%d",&v);
			addedge(1001,v,0);
			addedge(v,1001,0);
		}
		int ans=spfa();
		cout << ans <<endl;
	}
	return 0;
}
/ 
//                        HDU 2544                     //
//  Created by 吴尔立 <span style="white-space:pre">			</span>                       //
//  Copyright (c) 2015年 吴尔立. All rights reserved.  //
/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>           
#include <algorithm>
#include <cctype>
#include <stack>
#include <queue>
#include <map>
#include <string>
#include <set>
#include <vector>
#define ll long long;
#define INF 1<<31
#define cir(i,a,b)  for (int i=a;i<=b;i++)
#define CIR(j,a,b)  for (int j=a;j>=b;j--)
#define CLR(x) memset(x,0,sizeof(x))
using namespace std;
const int maxn = 10005;
int N, M;  //N个路口M条路; 
int A, B, C;   //A到B用时为C
int pnt[maxn], pre[maxn], head[maxn], d[maxn], dis[maxn]; //d[i] 表示从起点到 i 但的最短路 
int counter[maxn], vis[maxn];
int cnt = 0;
 
void addedge(int u, int v, int w) {
    pnt[cnt] = v; pre[cnt] = head[u]; dis[cnt] = w; head[u] = cnt++;
}
 
int spfa(int s) {
    queue<int> q;
    memset(d, -1, sizeof(d));
    CLR(vis);
    d[s] = 0;
    q.push(s);
    vis[s] = 1;
    while (!q.empty()) {
        int x = q.front();
        q.pop();
        for (int i = head[x]; i != -1; i = pre[i])   //遍历邻接表 
        {
            int y =  pnt[i];
            if (d[y] == -1 || d[x] + dis[i] < d[y]) {
                d[y] = d[x] + dis[i];
                if (!vis[y]) {
                    vis[y] = 1;
                    q.push(y);
                }
            }
        }
        vis[x] = 0;
    }
    return 0;
}
 
int main() {
    while (scanf("%d%d", &N, &M) != EOF && N != 0 && M != 0) {
        cnt = 0;
        CLR(dis);
        memset(head, -1, sizeof(head));
        cir(i, 1, M) {
            scanf("%d %d %d", &A, &B, &C);
            addedge(A, B, C);
            addedge(B, A, C);
        }
        spfa(1);
        cout << d[N] << endl;
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值