本题数据中没有 rank=10 的点,导致除了最后一篇的所有题解都在没有把 d11,i 设成极大值的情况下过掉了(d11,i 的意义是权值为 11 的点到点 i 的最短路,因为松弛时要求 disv<dranks+1,v,所以显然要设成极大值)。
并且数据也没有数据范围中所写的那么大,这篇题解甚至复杂度都是错的。
请求撤下所有题解并加强数据。
这个是数据生成器(不过并不能保证答案 ≤30n,所以造的时候如果遇到不符合条件的要删掉重造)
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<ctime>
using namespace std;
int n,m,x,y,t,i;
bool f[30005][30005];
int g[30005],id[30005],s,u,v;
int main()
{ freopen("servers5.in","w",stdout);
srand(time(0));
n=30000;
m=140000;
printf("%d %d\n",n,m);
for (i=1;i<=n;i++)
{ printf("%d\n",(rand()%9)+1);
//printf("1\n");
}
for (i=1;i<=n;i++) f[i][i]=1;
for (i=1;i<=n;i++) id[i]=i;
for (i=2;i<=n;i++)
{ x=rand()%(i-1),x++;
while (g[x]>9)
x=rand()%(i-1),x++;
t=rand()%1000,t++;
printf("%d %d %d\n",x,i,t);
g[i]++; g[x]++;
f[x][i]=f[i][x]=1;
}
for (i=n;i<=m;i++)
{ x=rand()%n,x++;
y=rand()%n,y++;
u=id[x],v=id[y];
while (f[u][v]||g[u]>9||g[v]>9)
x=rand()%n,x++,y=rand()%n,y++,u=id[x],v=id[y];
t=rand()%1000,t++;
printf("%d %d %d\n",u,v,t);
f[u][v]=f[v][u]=1;
g[u]++,g[v]++;
if (g[id[x]]>9)
{ s=id[x],id[x]=id[n],id[n]=s;n--;
}
if (g[id[y]]>9)
{ s=id[y],id[y]=id[n],id[n]=s;n--;
}
}
return 0;
}
这是 std
//Think twice,code once.
#include<queue>
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int n,m,ans,a[30005],d[15][30005];
int dis[30005];
bool f[30005];
struct node
{
int id,val;
node(int _id,int _val){id=_id;val=_val;}
friend bool operator<(node x,node y){return x.val>y.val;}
};
priority_queue<node>q;
struct graph
{
int tot,hd[30005];
int nxt[300005],to[300005],dt[300005];
void add(int u,int v,int w)
{
nxt[++tot]=hd[u];
hd[u]=tot;
to[tot]=v;
dt[tot]=w;
return ;
}
}g;
void dijkstra0(int val)
{
memset(d[val],0x3f,sizeof(d[val]));
memset(f,0,sizeof(f));
for(int i=1;i<=n;i++)
if(a[i]==val)
{
d[val][i]=0;
q.emplace(i,0);
}
while(!q.empty())
{
int now=q.top().id;
q.pop();
if(f[now]) continue;
f[now]=1;
for(int i=g.hd[now];i;i=g.nxt[i])
if(d[val][g.to[i]]>d[val][now]+g.dt[i])
{
d[val][g.to[i]]=d[val][now]+g.dt[i];
q.emplace(g.to[i],d[val][g.to[i]]);
}
}
return ;
}
void dijkstra(int s)
{
memset(dis,0x3f,sizeof(dis));
memset(f,0,sizeof(f));
dis[s]=0;
q.emplace(s,0);
while(!q.empty())
{
int now=q.top().id;
q.pop();
if(f[now]) continue;
f[now]=1;
ans++;
for(int i=g.hd[now];i;i=g.nxt[i])
if(dis[g.to[i]]>dis[now]+g.dt[i]&&dis[now]+g.dt[i]<d[a[s]+1][g.to[i]])
{
dis[g.to[i]]=dis[now]+g.dt[i];
q.emplace(g.to[i],dis[g.to[i]]);
}
}
return ;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
for(int i=1;i<=m;i++)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
g.add(u,v,w);
g.add(v,u,w);
}
memset(d,0x3f,sizeof(d));
for(int i=1;i<=10;i++) dijkstra0(i);
for(int i=9;i>=1;i--)
for(int j=1;j<=n;j++) d[i][j]=min(d[i][j],d[i+1][j]);
for(int i=1;i<=n;i++) dijkstra(i),printf("%d\n",ans);
printf("%d\n",ans);
return 0;
}
@dottle