这题经过的结点比较好处理。
主要是字典序的处理。
先是floyd做法,采用记录后驱的方法。 path[i][j]=j【初始化。。。】
#include
#include
#include
#include
using namespace std;
const int maxn=5000;
const int INF=100000000;
int n;
int node[maxn];
int dist[maxn][maxn];
int path[maxn][maxn];
void floyd()
{
for(int i=1;i<=n;i++)//初始化 有一种后驱的感觉
for(int j=1;j<=n;j++)
path[i][j]=j;
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
int temp=dist[i][k]+dist[k][j]+node[k];
if(dist[i][j]>temp)
{
dist[i][j]=temp;
path[i][j]=path[i][k];
}
if(dist[i][j]==temp)
{
if(path[i][j]>path[i][k])
path[i][j]=path[i][k];
}
}
}
int main()
{
int a,be,en;
while(scanf("%d",&n)&&n)
{
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
scanf("%d",&a);
if(a!=-1) dist[i][j]=a;
else dist[i][j]=INF;
}
for(int i=1;i<=n;i++) scanf("%d",&node[i]);
floyd();
int kcase=0;
while(1)
{
if(kcase!=0) printf("\n");
kcase++;
scanf("%d%d",&be,&en);
if(be==-1&&en==-1) break;
printf("From %d to %d :\n",be,en);
printf("Path: ");
printf("%d",be);
int temp=be;
while(temp!=en)
{
printf("-->%d",path[temp][en]);
temp=path[temp][en];
}
printf("\n");
printf("Total cost : %d\n",dist[be][en]);
}
}
return 0;
}
接下来是spfa的做法。
又提交了20+WA
本来就是想练一下输出前驱,结果。。。 某个地方竟然犯了一个我没想到的错。
首先是比较前面结点字典序时,应该从头开始。然后就是这个我会记一辈子的错了。。
邻接表做法
#include
#include
#include
#include
#include
using namespace std;
const int maxn=10005,INF=10000000;
queue q;
bool inq[maxn*2];
int first[maxn*2];
int next[maxn*2];
int p[maxn];
int u[maxn*2],v[maxn*2],w[maxn*2],d[maxn*2];
int str1[maxn],str2[maxn];
int n,m;
int map[maxn][maxn];
int node[maxn];
int dis[maxn];
void spfa(int be)
{
while(!q.empty()) q.pop();
for(int i=0;id[x]+w[e])
{
d[v[e]]=d[x]+w[e];
p[v[e]]=x;
if(!inq[v[e]])
{
inq[v[e]]=true;
q.push(v[e]);
}
}
else if(d[v[e]]==d[x]+w[e])//这一块遍历前趋没问题
{
int l1=0,l2=0;
int temp=v[e];
while(temp!=be)
{
str1[l1++]=temp;
temp=p[temp];
}
temp=x;
while(temp!=be)
{
str2[l2++]=temp;
temp=p[temp];
}
for(int i=l1-1,j=l2-1;i>=0&&j>=0;i--,j--)
{
if(str1[i]>str2[j])
{
p[v[e]]=x;
break;
}
else if(str1[i]",a+1,b+1,a+1);
for(int i=l-1;i>=0;i--){
printf("%d-->",dis[i]+1);
}
printf("%d\nTotal cost : %d\n\n",b+1,d[b]-node[b]);
}
}
return 0;
}
哈哈,想了终于明白这个地方 temp=v[e]了。
比如1 2 4 还有一个是1 2 3 4 显然第二种比第一种字典序更靠前。
但自己不是temp=v[e]的话就少了这种情况。
如果是1 2 3 4和1 2 4则可以成功。
自己可以生成一个案例。
终于明白,呵~~~~~~~~~~~~
错这么多次也是值得的,至少自己验证了模板和自己某些方面的不严谨性。
4
-1 1 -1 -1
1 -1 2 3
-1 2 -1 1
-1 3 1 -1
0 0 0 0
1 4
From 1 to 4 :
Path: 1-->2-->4
Total cost : 4