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 
#include 
#include 
#include 
#include            
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#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 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]> 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 <
///////////////////////////////////////////////////////// 
//                        HDU 2544                     //
//  Created by 吴尔立 			                       //
//  Copyright (c) 2015年 吴尔立. All rights reserved.  //
/////////////////////////////////////////////////////////
#include 
#include 
#include 
#include 
#include            
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#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 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;
}


你可能感兴趣的:(ACM学习之路——HDU2544 HDU2066(spfa))