| 比赛 |
csp2025模拟练习3 |
评测结果 |
AAAAAAAAAA |
| 题目名称 |
Minimum Cost Roads |
最终得分 |
100 |
| 用户昵称 |
梦那边的美好TE |
运行时间 |
1.821 s |
| 代码语言 |
C++ |
内存使用 |
71.16 MiB |
| 提交时间 |
2025-10-30 11:13:49 |
显示代码纯文本
#include <bits/stdc++.h>
#define int long long
#define pii pair<int,int>
#define mp make_pair
using namespace std;
const int N=2005;
int n,m,w[N][N],c[N][N],f[N],val[N][N],co[N][N];
int ver[N<<1],to[N<<2],nxt[N<<2],idx=1;
int dis[N<<1],mk[N<<1],edge[N],tot,ans,cnt,id;
priority_queue<pii>q;
void add(int x,int y){
to[++idx]=y,nxt[idx]=ver[x],ver[x]=idx;
}
struct node{int u,v,w;}e[N];
bool cmp(node a,node b){
return a.w<b.w;
}
int dijsktra(int s,int t){
memset(dis,0x3f,sizeof(dis));
memset(mk,0,sizeof(mk));
q.push(mp(0,s)),mk[s]=1,dis[s]=0;
while(q.size()){
int x=q.top().second;
q.pop();
for(int i=ver[x];i;i=nxt[i]){
int y=to[i];
if((x==s&&y==t)||(x==t&&y==s))continue;
if(dis[y]>dis[x]+val[x][y]){
dis[y]=dis[x]+val[x][y];
q.push(mp(-dis[y],y));
}
}
}
return dis[t];
}
int found(int x){
return f[x]==x?x:f[x]=found(f[x]);
}
signed main(){
freopen("Roads.in","r",stdin);
freopen("Roads.out","w",stdout);
scanf("%lld %lld",&n,&m);
memset(w,0x3f,sizeof(w));
for(int i=1,u,v,len,cost;i<=m;i++){
scanf("%lld %lld %lld %lld",&u,&v,&len,&cost);
if(len<w[u][v]){
w[u][v]=w[v][u]=len;
c[u][v]=c[v][u]=cost;
}else if(len==w[u][v]){
c[u][v]=c[v][u]=min(c[u][v],cost);
}
}
for(int i=1;i<=n;i++)f[i]=i;
for(int i=1;i<=n;i++){
for(int j=i+1;j<=n;j++){
if(w[i][j]==0){
e[++cnt]=node{i,j,c[i][j]};
}
}
}
sort(e+1,e+1+cnt,cmp);
for(int i=1,u,v;i<=cnt;i++){
u=found(e[i].u);
v=found(e[i].v);
if(u!=v)f[u]=v,ans+=e[i].w;
}
memset(val,0x3f,sizeof(val));
for(int i=1;i<=n;i++){
for(int j=i+1;j<=n;j++){
if(w[i][j]==0x3f3f3f3f3f3f3f3f)continue;
if(w[i][j]==0)continue;
int u=found(i),v=found(j);
int len=w[i][j],cost=c[i][j];
if(len<val[u][v]){
val[u][v]=val[v][u]=len;
co[u][v]=co[v][u]=cost;
}else if(len==val[u][v]){
co[u][v]=co[v][u]=min(co[u][v],cost);
}
}
}
for(int i=1;i<=n;i++){
for(int j=i+1;j<=n;j++){
if(val[i][j]!=0x3f3f3f3f3f3f3f3f){
add(i,j),add(j,i);
edge[++tot]=idx;
}
}
}
for(int i=1;i<=tot;i++){
int e=edge[i],u=to[e],v=to[e^1];
if(dijsktra(u,v)>val[u][v]){
ans+=co[u][v];
}
}
printf("%lld\n",ans);
return 0;
}