每日一題-P1261

Kent530發表於2024-07-23

其實想到方法了,但是以為複雜度炸了,好蠢

#include<bits/stdc++.h>
using namespace std;
#define pb push_back
int n,m,rk[30005],f[30005],g[30005],dis[30005],ans;
bool vis[30005];
vector<int> s;
struct edge{
	int v,w,nx;
}e[300005];
int cnt,hd[30005];
void add(int u,int v,int w){
	e[++cnt]=edge{v,w,hd[u]};
	hd[u]=cnt;
}
void add_edge(int u,int v,int w){
	add(u,v,w);add(v,u,w);
}
struct node{
	int u,l;
};
bool operator<(const node&x,const node&y){
	return x.l>y.l;
}
void dij(int st){
	priority_queue<node> pq;pq.push(node{st,0});
	dis[st]=0;
	while(!pq.empty()){
		int u=pq.top().u;pq.pop();
		if(vis[u])continue;
		vis[u]=1;ans++;s.pb(u);
		for(int i=hd[u];i;i=e[i].nx){
			int v=e[i].v;if(vis[v] || f[v]<=dis[u]+e[i].w || dis[v]<=dis[u]+e[i].w)continue;
			dis[v]=dis[u]+e[i].w;
			pq.push(node{v,dis[v]}); 
		} 
	}
	for(int u:s)g[u]=min(g[u],dis[u]),dis[u]=0x3f3f3f3f,vis[u]=0;
	s.clear();
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)scanf("%d",&rk[i]);
	for(int i=1;i<=m;i++){
		int u,v,w;scanf("%d%d%d",&u,&v,&w);
		add_edge(u,v,w);
	}
	memset(dis,0x3f,sizeof(dis));
	memset(f,0x3f,sizeof(f));
	for(int i=10;i>=1;i--){
		memset(g,0x3f,sizeof(g));
		for(int j=1;j<=n;j++)
			if(rk[j]==i)
				dij(j);
		for(int j=1;j<=n;j++)f[j]=min(f[j],g[j]);
	}
	printf("%d\n",ans);
	return 0;
} 

相關文章