题目链接
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;
}