我好菜,题目看着很简单,实际确实很简单,但是还是wa了很多遍。先是白痴地试了一下Floyd,不出意外地超时了。然后直接上手Dijkstra,结果wa了,我,,,确实菜。然后就写了一边Bellman-Ford,ac了,回头的就发现了Dijkstra的问题出在对dis[i]的初始化。
目录
Floyd算法,超时。
#include<iostream>
#include<algorithm>
using namespace std;
const int inf = 0x3f3f3f3f;
const int num = 1010;
int t, s, d, maxv;
int dis[num][num];
void floyd(){
for(int k=0; k<maxv; k++)
for(int i=0; i<maxv; i++)
for(int j=0; j<maxv; j++)
if(dis[i][k]<inf && dis[k][j]<inf)
if(dis[i][j] > dis[i][k]+dis[k][j])
dis[i][j] = dis[i][k]+dis[k][j];
}
int main(){
while(~scanf("%d%d%d", &t, &s, &d)){
maxv = 0;
for(int i=0; i<num; i++){
for(int j=0; j<num; j++)
dis[i][j] = inf;
dis[i][i] = 0;
}
while(t--){
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
if(a>maxv) maxv = a;
if(b>maxv) maxv = b;
int x = min(dis[a][b], c);
dis[a][b] = dis[b][a] = x;
}
while(s--){
int a;
scanf("%d", &a);
dis[0][a] = 0;
}
floyd();
int mint = inf;
while(d--){
int v;
scanf("%d", &v);
if(dis[0][v] < mint) mint = dis[0][v];
}
printf("%d\n", mint);
}
return 0;
}
Dijkstra,WA。
按习惯,把dis[i]的初始化写在了函数里。
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
const int inf = 0x3f3f3f3f;
const int num = 1010;
int t, s, d;
int dis[num];
int pre[num];
int done[num];
struct edge{
int from, to, w;
edge(int u, int v, int d){from=u;to=v;w=d;}
};
vector<edge>e[num];
struct node{
int id, dist;
node(int u, int d){id=u;dist=d;}
bool operator <(const node &a)const
{ return dist > a.dist;}
};
void dijkstra(){
for(int i=1; i<num; i++){
dis[i] = inf;
pre[i] = done[i] = 0;
}
priority_queue<node>q;
q.push(node(0, 0));
while(!q.empty()){
node u = q.top();
q.pop();
if(done[u.id]) continue;
done[u.id] = 1;
for(int i=0; i<e[u.id].size(); i++){
edge y = e[u.id][i];
if(done[y.to]) continue;
if(dis[y.to] > u.dist + y.w){
dis[y.to] = u.dist + y.w;
q.push(node(y.to, dis[y.to]));
pre[y.to] = u.id;
}
}
}
}
int main(){
while(~scanf("%d%d%d", &t, &s, &d)){
for(int i=0; i<num; i++) e[i].clear();
while(t--){
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
e[a].push_back(edge(a, b, c));
e[b].push_back(edge(b, a, c));
}
while(s--){
int a;
scanf("%d", &a);
e[0].push_back(edge(0, a, 0));
e[a].push_back(edge(a, 0, 0));
}
dijkstra();
int mint = inf;
while(d--){
int v;
scanf("%d", &v);
if(dis[v] < mint) mint = dis[v];
}
printf("%d\n", mint);
}
return 0;
}
Dijkstra,AC。
写完Bellman-Ford的代码之后,我把对dis[i]的初始化写道了主函数下。这题特殊就特殊在有s个城市是和家乡相邻的,而这个相邻的距离直接为0.(呃啊,我有点解释不清,但把dis[i]的初始化改变位置以后确实ac了)
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
const int inf = 0x3f3f3f3f;
const int num = 1010;
int t, s, d;
int dis[num];
int done[num];
struct edge{
int from, to, w;
edge(int u, int v, int d){from=u;to=v;w=d;}
};
vector<edge>e[num];
struct node{
int id, dist;
node(int u, int d){id=u;dist=d;}
bool operator <(const node &a)const
{ return dist > a.dist;}
};
void dijkstra(){
priority_queue<node>q;
q.push(node(0, 0));
while(!q.empty()){
node u = q.top();
q.pop();
if(done[u.id]) continue;
done[u.id] = 1;
for(int i=0; i<e[u.id].size(); i++){
edge y = e[u.id][i];
if(done[y.to]) continue;
if(dis[y.to] > u.dist + y.w){
dis[y.to] = u.dist + y.w;
q.push(node(y.to, dis[y.to]));
}
}
}
}
int main(){
while(~scanf("%d%d%d", &t, &s, &d)){
for(int i=0; i<num; i++){
e[i].clear();
dis[i] = inf;
done[i] = 0;
}
dis[0] = 0;
while(t--){
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
e[a].push_back(edge(a, b, c));
e[b].push_back(edge(b, a, c));
}
while(s--){
int a;
scanf("%d", &a);
e[0].push_back(edge(0, a, 0));
e[a].push_back(edge(a, 0, 0));
}
dijkstra();
int mint = inf;
while(d--){
int v;
scanf("%d", &v);
if(dis[v] < mint) mint = dis[v];
}
printf("%d\n", mint);
}
return 0;
}
Bellman-Ford,AC。
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
const int num = 1001;
const int inf = 0x3f3f3f3f;
int t, s, d;
int dis[num];//到原点距离
int pre[num];//记录前驱节点
struct edge{
int u, v, w;
edge(int a, int b, int c){u=a;v=b;w=c;}
};
vector<edge>e;
void print_path(int u, int v){//输出路径
if(u==v) printf("%d", u);
print_path(u, pre[v]);
printf("->%d", v);
}
void bellman(){
int k=0, flag=1;
while(flag){
k++;
flag = 0;
for(int i=0; i<2*t; i++){
if(dis[e[i].u] > dis[e[i].v] + e[i].w){
dis[e[i].u] = dis[e[i].v] + e[i].w;
flag = 1;
pre[e[i].u] = e[i].v;
}
}
}
}
int main(){
while(~scanf("%d%d%d", &t, &s, &d)){
e.clear();
for(int i=0; i<num; i++)
dis[i] = inf;
dis[0] = 0;
for(int i=0; i<t; i++){
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
e.push_back(edge(a, b, c));
e.push_back(edge(b, a, c));
}
while(s--){
int a;
scanf("%d", &a);
dis[a] = 0;
}
bellman();
int mint = inf;
while(d--){
int a;
scanf("%d", &a);
if(mint>dis[a]) mint = dis[a];
}
printf("%d\n", mint);
}
return 0;
}