题目大意:不告诉你QAQ
跑dij时处理一下就好辣
顺便说一下dij的复杂度
不加堆优化的是n^2
加了之后就是mlogn
因为我们每修改一次dis,堆里面就要进行一次操作(而我们是通过m条边松弛dis的)
而这道题就直接在dij加点东西就可以了
if(dis[j]>dis[rr]+map[rr][j]) 记录f[j]=rr;
if(dis[j]==dis[rr]+map[rr][j]) 则把f[j]清零
这样最后不是0的,就是关键点辣
然后注意跑最短路算法时初始化那些边权的时候要小心相加爆int
#include<cstdio>
#include<cstring>
const int N=207;
int cnt;
int map[N][N];
int f[N];
int tag[N],dis[N],visit[N];
int n,m;
inline int min(int a,int b)
{
return a<b?a:b;
}
void work(int s)
{
memset(dis,63,sizeof(dis));
memset(visit,0,sizeof(visit));
memset(f,0,sizeof(f));
dis[s]=0;
for(int i=1;i<=n;i++)
{
int min=2*1e9,jj=0;
for(int j=1;j<=n;j++)
if(!visit[j]&&dis[j]<min) min=dis[j],jj=j;
visit[jj]=1;
for(int j=1;j<=n;j++)
if(!visit[j])
{
if(dis[j]>dis[jj]+map[jj][j]) dis[j]=dis[jj]+map[jj][j],f[j]=jj;
else if(dis[j]==dis[jj]+map[jj][j]) f[j]=0;
}
}
for(int i=1;i<=n;i++) if(f[i]&&f[i]!=s) tag[f[i]]=1;
}
int main()
{
freopen("city.in","r",stdin);
freopen("city.out","w",stdout);
scanf("%d %d",&n,&m);
memset(map,63,sizeof(map));
for(int i=1;i<=m;i++)
{
int u,v,q;
scanf("%d %d %d",&u,&v,&q);
map[u][v]=min(map[u][v],q);
map[v][u]=min(map[v][u],q);
}
for(int i=1;i<=n;i++) work(i);
int sum=0;
for(int i=1;i<=n;i++) if(tag[i]) sum++,printf("%d ",i);
if(!sum) printf("No important cities.\n");
fclose(stdin);
fclose(stdout);
return 0;
}