CSP-201903-5 317号子任务/60分

只能想到60分做法,前60%据点数量相对不大大约在10^2这个数量级,对于每个据点跑一次dij然后统计下前k小就好了。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define inf 0x3f3f3f3f
 4 #define pii pair<int,int>
 5 #define mp  make_pair
 6 class Edge{
 7 public:
 8     int v,w;
 9     Edge(){}
10     Edge(int v,int w){this->v=v;this->w=w;}
11 };
12 const int maxn=11111;
13 int N,M,K,u,v,w,tot;
14 int type[maxn];
15 vector<Edge>g[maxn];
16 vector<int>vi;
17 int d[1025][maxn];
18 bool vis[maxn];
19 void gao(int n,int d[]){
20     memset(d,inf,sizeof(int)*(N+2));
21     memset(vis,0,sizeof(vis));
22     d[n]=0;
23     priority_queue<pii,vector<pii>,greater<pii> >q;
24     q.push(mp(0,n));
25     while(!q.empty()){
26         int u=q.top().second;q.pop();
27         if(vis[u])continue;
28         vis[u]=1;
29         for(Edge e:g[u]){
30             if(d[u]+e.w<d[e.v]){
31                 d[e.v]=d[u]+e.w;
32                 q.push(mp(d[e.v],e.v));
33             }
34         }
35     }
36 }
37 int main(){
38     scanf("%d%d%d",&N,&M,&K);
39     for(int i=1;i<=N;++i){
40     scanf("%d",&type[i]);
41     if(type[i]) vi.push_back(i);
42     }
43     for(int i=1;i<=M;++i){
44         scanf("%d%d%d",&u,&v,&w);
45         g[u].push_back(Edge(v,w));
46         g[v].push_back(Edge(u,w));
47     }
48     for(int i=0;i<vi.size();++i){
49         gao(vi[i],d[i]);
50     }
51     if(vi.size()<K)K=vi.size();
52     for(int i=1;i<=N;++i){
53         int sz=vi.size();
54         vector<int>v;
55         for(int j=0;j<sz;++j){
56             v.push_back(d[j][i]);
57         }
58         sort(v.begin(),v.end());
59         int ans=0;
60         for(int j=0;j<K && v[j]!=inf;++j)ans+=v[j];
61         printf("%d
",ans);
62     }
63     return 0;
64 }
65 /*
66 7 6 2
67 1 0 1 0 1 1 0
68 1 4 1
69 1 2 3
70 2 4 4
71 2 3 5
72 2 5 7
73 6 7 5
74 
75 */
原文地址:https://www.cnblogs.com/zzqc/p/12341867.html