本题是一个比较裸的 Floyd 练习题,然而我的 Floyd 出锅了,不知怎么回事。
众所周知用邻接矩阵存图进行 Floyed 后 dis[x][y]=dis[y][x]
,可是:
当我输出 dis[x][y]
时,只有 20 分,当将输出改为 min(ans[x][y],ans[y][x])
时,便可 AC。
为啥?
下面是代码:
#include"iostream"
#include"cstdio"
#include"cmath"
#include"algorithm"
using namespace std;
#define read(x) scanf("%d",&x)
#define inf 1e9
int n,m,q;
struct node
{
int id,val;
}a[255];
struct edge
{
int to,nxt,w;
}e[10005<<1];
int head[255],cnt=0;
int dis[255][255]={0};
int x,y,z;
int st[255],top=0;
int ans[255][255];
bool cmp(node x,node y){return x.val<y.val;}
void add(int u,int v,int w)
{
e[++cnt].to=v;
e[cnt].w=w;
e[cnt].nxt=head[u];
head[u]=cnt;
}
int main()
{
//freopen("data.in","r",stdin);
//freopen("data.out","w",stdout);
read(n),read(m),read(q);
for(int i=1;i<=n;i++) read(a[i].val),a[i].id=i;
sort(a+1,a+n+1,cmp);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(i^j) dis[i][j]=inf;
else dis[i][j]=0;
ans[i][j]=dis[i][j];
}
}
for(int i=1;i<=m;i++)
{
read(x),read(y),read(z);
add(x,y,z),add(y,x,z);
}
for(int i=1;i<=n;i++)
{
int u=a[i].id;
for(int k=head[u];k;k=e[k].nxt)
{
int j=e[k].to;
dis[j][u]=dis[u][j]=min(dis[u][j],e[k].w);
}
if(top>=2)
{
for(int j=1;j<=top;j++)
{
for(int k=1;k<=top;k++)
{
if(j==k) continue;
int tj=st[j],tk=st[k];
dis[u][tj]=min(dis[u][tj],dis[u][tk]+dis[tk][tj]);
dis[tj][u]=min(dis[tj][u],dis[tj][tk]+dis[tk][u]);
dis[tj][tk]=min(dis[tj][tk],dis[tj][u]+dis[u][tk]);
}
}
}
st[++top]=u;
for(int j=1;j<=top;j++)
{
for(int k=1;k<=top;k++)
{
int tj=st[j],tk=st[k];
if(dis[tj][tk]==inf) continue;
ans[tj][tk]=min(ans[tj][tk],dis[tj][tk]+a[i].val);
}
}
}
while(q--) read(x),read(y),printf("%d\n",/*min(ans[x][y],ans[y][x])*/ans[x][y]);//这里是问题所在,注释了正确做法,留下了 20 分做法。
return 0;
}