用全源最短路径只能得60,因为数据太大了,全源最短大概复杂度为O(n*m*logn),大概要1-2秒左右超时,想不到好的算法qaq。
#include<bits/stdc++.h> using namespace std; #define maxn 10003 vector<pair<int,int> > ss[maxn]; int jl[maxn][maxn]; int f[maxn]; int ff(int x){ if(f[x]==x)return x; int k=f[x]; f[x]=f[k]; return ff(k); } void unionnode(int n,int m){ int a=ff(n),b=ff(m); if(a==b)return ; f[a]=b;return ; } bool pd(int a,int b){ return ff(a)==ff(b); } int main(){ ios::sync_with_stdio(false); int n,m,k;cin>>n>>m>>k; vector<int> ll; int d[n+1]; for(int i=1;i<n+1;i++){ cin>>d[i]; if(d[i]){ ll.push_back(i); } } for(int i=1;i<maxn;i++){ f[i]=i; } while(m--){ int a,b,c; cin>>a>>b>>c; unionnode(a,b); ss[a].push_back({b,c}); ss[b].push_back({a,c}); } memset(jl,0x3f,sizeof(jl)); for(int i=1;i<n+1;i++){ jl[i][i]=0; } priority_queue<pair<int,int> > q; for(auto i:ll){ while(!q.empty())q.pop(); for(int j=1;j<=i;j++){ if(jl[i][j]!=jl[0][0])q.push({0,j}); } int vis[n+1]={0}; while(!q.empty()){ int b=q.top().second;q.pop(); if(vis[b])continue; vis[b]=1; for(int j=0;j<ss[b].size();j++){ int node=ss[b][j].first,t=ss[b][j].second; if(vis[node])continue; if(jl[i][b]+t>=jl[i][node])continue; jl[i][node]=jl[i][b]+t; q.push({-jl[i][node],node}); } } } int sz[maxn]; for(int i=1;i<n+1;i++){ int cnt=0; long long cost=0; for(auto x:ll){ if(pd(i,x)){ sz[cnt++]=jl[x][i]; } } sort(sz,sz+cnt); for(int j=0;j<min(cnt,k);j++){ cost+=sz[j]; } cout<<cost; i==n||cout<<endl; } return 0; } /* 7 6 2 1 0 1 0 1 1 0 1 4 1 1 2 3 2 4 4 2 3 5 2 5 7 6 7 5 */