D. Fair
http://codeforces.com/contest/987/problem/D
题意:
n个城镇m条道路,(保证没有重边,两个城镇间可以到达),每个城镇拥有的特产ai(可能多个城镇有相同特产)。总共有k种不同特产。每个城镇举办展会需要至少s种特产,一份特产从一个城镇运到另一个城镇的花费为最短路(每次只能运一个)。求出在每个城镇举办展会的最小花费。
分析:
bfs。
如果直接枚举每个城镇作为举办展会,然后计算到每个特产的最短路,取出前s个,复杂度n^2。
发现k<=100,所以可以反过来枚举,枚举每种特产到每个城镇的最短路,多源bfs跑一下,最后枚举每个诚镇计算答案。
代码:
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #include<cmath> 5 #include<iostream> 6 #include<cctype> 7 #include<set> 8 #include<vector> 9 #include<queue> 10 #include<map> 11 #define fi(s) freopen(s,"r",stdin); 12 #define fo(s) freopen(s,"w",stdout); 13 using namespace std; 14 typedef long long LL; 15 16 inline int read() { 17 int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch==‘-‘)f=-1; 18 for(;isdigit(ch);ch=getchar())x=x*10+ch-‘0‘;return x*f; 19 } 20 21 const int N = 100005; 22 const int INF = 1e9; 23 24 struct Edge{ 25 int to, nxt; 26 }e[N << 1]; 27 int head[N], En, dis[N][105], q[N]; 28 vector<int> vec[105]; 29 30 void add_edge(int u,int v) { 31 ++En; e[En].to = v; e[En].nxt = head[u]; head[u] = En; 32 ++En; e[En].to = u; e[En].nxt = head[v]; head[v] = En; 33 } 34 35 void bfs(int x) { 36 int L = 1, R = 0; 37 for (int sz = vec[x].size(), i = 0; i < sz; ++i) { 38 q[++R] = vec[x][i]; 39 dis[vec[x][i]][x] = 0; 40 } 41 while (L <= R) { 42 int u = q[L++]; 43 for (int i = head[u]; i; i = e[i].nxt) { 44 int v = e[i].to; 45 if (dis[v][x] == INF) { 46 dis[v][x] = dis[u][x] + 1; 47 q[++R] = v; 48 } 49 } 50 } 51 } 52 53 int main() { 54 int n = read(), m = read(), k = read(), s = read(); 55 for (int i = 1; i <= n; ++i) vec[read()].push_back(i); 56 for (int i = 1; i <= m; ++i) { 57 int u = read(), v = read(); 58 add_edge(u, v); 59 } 60 for (int i = 1; i <= k; ++i) { 61 for (int j = 1; j <= n; ++j) dis[j][i] = INF; 62 bfs(i); 63 } 64 65 for (int i = 1; i <= n; ++i) { 66 int ans = 0; 67 sort(dis[i] + 1, dis[i] + k + 1); 68 for (int j = 1; j <= s; ++j) ans += dis[i][j]; 69 printf("%d ",ans); 70 } 71 72 return 0; 73 }
原文地址:https://www.cnblogs.com/mjtcn/p/9911755.html
时间: 2024-10-08 11:00:18