比赛 csp2025模拟练习3 评测结果 WATWWWWWWW
题目名称 Minimum Cost Roads 最终得分 10
用户昵称 会挽弯弓满月 运行时间 5.897 s
代码语言 C++ 内存使用 10.87 MiB
提交时间 2025-10-30 11:30:23
显示代码纯文本
#include <bits/stdc++.h>
using namespace std;
const int N=2010,inf=1e9+7;
int read(){
	int x=0,f=1;
	char c=getchar();
	while(c<48||c>57){
		if(c==45) f=-1;
		c=getchar();
	}
	while(c>=48&&c<=57){
		x=(x<<1)+(x<<3)+c-48;
		c=getchar();
	}
	return f*x;
}
int n,m;
int dis[N][N];
struct node{
	int to,nxt,val,cost;
}e[N<<1];
int h[N],tot;
void add(int u,int v,int w,int c){
	e[++tot]={v,h[u],w,c};
	h[u]=tot;
	return;
}
struct edge{
	int len,id;
	friend bool operator <(const edge &a,const edge &b){
		return a.len>b.len;
	}
};
priority_queue<edge> q;
bool vis[N];
void dijkstra(int x){
	while(q.size()) q.pop();
	memset(vis,0,sizeof(vis));
	for(int i=1;i<=n;i++) dis[x][i]=inf;
	dis[x][x]=0;
	q.push((edge){0,x});
	int u,v,w;
	while(q.size()){
		u=q.top().id;q.pop();
		if(vis[u]) continue;
		vis[u]=1;
		for(int i=h[u];i;i=e[i].nxt){
			v=e[i].to;w=e[i].val;
			if(dis[x][v]>dis[x][u]+w){
				dis[x][v]=dis[x][u]+w;
				if(!vis[v]) q.push((edge){dis[x][v],v});
			}
		}
	}
	return;
}
struct que{
	int u,v,l,c;
}qn[N];
bool ce[N];
int cnt;
struct nnode{
	int u,v,l,c;
}ed[N];
bool cmp(nnode a,nnode b){
	return a.c<b.c;
}
int Dis[N][N];
void solve(){
	for(int i=1;i<=n;i++) dijkstra(i);
	int len,u,v,c;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			len=qn[j].l;
			u=qn[j].u;v=qn[j].v;
			if(dis[i][u]+len==dis[i][v]) ce[j]=1;
			if(dis[i][v]+len==dis[i][u]) ce[j]=1;
		}
	}
	for(int i=1;i<=m;i++){
		if(ce[i]){
			u=qn[i].u;v=qn[i].v;
			len=qn[i].l;c=qn[i].c;
			ed[++cnt]={u,v,len,c};
		}
	}
	sort(ed+1,ed+cnt+1,cmp);
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			if(i==j) Dis[i][j]=0;
			else Dis[i][j]=inf;
		}
	}
	int sumc=0,now;
	bool flag;
	for(int k=1;k<=cnt;k++){
		u=ed[k].u;v=ed[k].v;
		len=ed[k].l;c=ed[k].c;
		flag=1;
		if(Dis[u][v]<=len) flag=0;
		if(flag){
			sumc+=c;
			for(int i=1;i<=n;i++){
				for(int j=1;j<=n;j++){
					if(Dis[i][u]<inf&&Dis[v][j]<inf){
						now=Dis[i][u]+len+Dis[v][j];
						if(now<Dis[i][j]) Dis[i][j]=now;
					}
					if(Dis[i][v]<inf&&Dis[u][j]<inf){
						now=Dis[i][v]+len+Dis[u][j];
						if(now<Dis[i][j]) Dis[i][j]=now;
					}
				}
			}
		}
	}
	printf("%d",sumc);
}
int main(){
	freopen("Roads.in","r",stdin);
	freopen("Roads.out","w",stdout);
	n=read();m=read();
	int u,v,l,c;
	for(int i=1;i<=m;i++){
		u=read();v=read();l=read();c=read();
		add(u,v,l,c);add(v,u,l,c);
		qn[i]={u,v,l,c};
	}
	solve();
	return 0;
}