ICPC 2025 网络赛第一场 M

这道题我本来是建立多层图然后跑dijkstra来解决,但是由于N=5000,所以会包空间导致RE或者MLE,注意到其实这道题是从1到n都来一遍,其实就可以考虑k-1和k的关系,k在k-
1的基础上面跑最短路,跑完了之后我们对比传送门的两个点到1的距离,这样它可以更新新的最短路。

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> P;
const int N=1e6+10;
const int INF=0x3f3f3f3f;
int n,m,k;
int s,t;
struct edge
{
    int to,cost;
};
vector<edge> g[N];
long long d[N];
void add(int u,int v,int cost)
{
    edge e;
    e.cost=cost;
    e.to=v;
    g[u].push_back(e);
}
priority_queue< P,vector<P>,greater<P> > q;
int vis[N];
void dijkstra(int s)
{
    for(int i=1;i<=n;i++) q.push(P(d[i],i)),vis[i]=0;
    q.push(P(0,s));
    while(!q.empty())
    {
        P now=q.top();
        q.pop();
        int v=now.second;
        if(d[v]<now.first) continue;
        for(int i=0;i<g[v].size();i++)
        {
            edge e=g[v][i];
            if(d[e.to]>d[v]+e.cost)
            {
                d[e.to]=e.cost+d[v];
                q.push(P(d[e.to],e.to));
            }
        }
    }
}
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n-1;i++)
    {
        int u,v,w;
        cin>>u>>v>>w;
        add(u,v,w);
        add(v,u,w);
        
    }
    int U[N],V[N];
    for(int i=1;i<=m;i++)
	{
		cin>>U[i]>>V[i];
	} 
    for(int A=0;A<=n;A++)
    {
    	dijkstra();
	}
    return 0;
}
``
以下是正确代码

include <bits/stdc++.h>

define int long long

using namespace std;
const int N=5500,inf=1e18;
int n,m,d[N],dd[N];
struct edge{
int to,w;
edge(int to=0,int w=0):to(to),w(w){}
};
vector g[N];
int U[N2],V[N2];
struct node{
int x,y;
node(int x=0,int y=0):x(x),y(y){}
bool operator < (const node& )const{return y>.y;}
};
priority_queue Q;
int vis[N];

void dij(){
for(int i=1;i<=n;i++)Q.push(node(i,d[i])),vis[i]=0;
while(!Q.empty()){
int u=Q.top().x;
Q.pop();
if(vis[u]++)continue;
for(unsigned i=0;i<g[u].size();i++){
int v=g[u][i].to;
if(d[u]+g[u][i].w<d[v]){
d[v]=d[u]+g[u][i].w;
Q.push(node(v,d[v]));
}
}
}
return;
}

signed main(){
cin>>n>>m;
for(int i=1,u,v,w;i<n;i++){
cin>>u>>v>>w;
g[u].push_back(edge(v,w));
g[v].push_back(edge(u,w));
}
for(int i=1;i<=m;i++){
cin>>U[i]>>V[i];
}
for(int i=2;i<=n;i++){
d[i]=inf;
}
for(int T=0;T<=n;T++){
dij();
int ans=0;
for(int i=1;i<=n;i++)dd[i]=d[i],ans+=d[i];
for(int i=1;i<=m;i++){
dd[U[i]]=min(dd[U[i]],d[V[i]]);
dd[V[i]]=min(d[U[i]],dd[V[i]]);
}
for(int i=1;i<=n;i++)d[i]=min(d[i],dd[i]);
printf("%lld\n",ans);
}
return 0;
}
``

posted @ 2025-09-13 15:31  曾翎一  阅读(29)  评论(0)    收藏  举报