Examples
inputCopy
5 5 4 3
1 2 4 3 2
1 2
2 3
3 4
4 1
4 5
outputCopy
2 2 2 2 3
inputCopy
7 6 3 2
1 2 3 3 2 2 1
1 2
2 3
3 4
2 5
5 6
6 7
outputCopy
1 1 1 2 2 1 1
题意:n个城市,m条边(无向),保证每个城市都是联通的,每个城市有且只有一种颜色,共有k种颜色。从城市i出发,要获得s种颜色,且要保证代价最小,获取某种颜色的代价为两个城市间的最短路径
分别求从每个城市出发获取s种颜色的最小代价。
思路:
1.把颜色为c(1=<c<=k)的城市放在同一层(放入队列),进行bfs,即可得到所有城市获取颜色c的最小代价
2.进行k次BFS,就可以每个城市获取每种颜色的最小代价
3.对于每一个城市,取代价最小的前k种颜色。
我是把颜色c,看作城市n+c,然后对颜色为c的城市(假设为u)建一条有向边,即建边<n+c,u>;然后从每种颜色n+c(1=<c<=k)进行BFS
#include<iostream>
#include<cstdio>
#include<queue>
#include<cmath>
#include<vector>
#include<algorithm>
#define scan(i) scanf("%d",&i)
#define scanl(i) scanf("%I64d",&i)
#define print(i) printf("%d",i)
#define printl(i) printf("%I64d",i)
#define py() puts("Yes")
#define pn() puts("No")
#define repi(LL,RR) for(long long i=LL;i<=RR;i++)
#define repj(LL,RR) for(long long j=LL;j<=RR;j++)
#define rpei(RR,LL) for(long long i=RR;i>=LL;i--)
#define rpej(RR,LL) for(long long j=RR;j>=LL;j--)
#define cout(nnn) cout<<nnn<<"----"<<endl;
using namespace std;
typedef long long ll;
int n,m,k,s;
vector<int>g[100005+200],res[100005+200];
queue<int>q;
bool vis[100005+200];
void ins(int x ,int y){
g[x].push_back(y);
}
void bfs(int st){
repi(1,n)vis[i]=0;
q.push(st);
int dp=-2;
while(!q.empty()){
int len=q.size();
dp++;
while(len--){
int tp=q.front();
//cout<<tp<<" :tp"<<endl;
q.pop();
vis[tp]=1;
res[tp].push_back(dp);
int l=g[tp].size();
repi(0,l-1){
int id=g[tp][i];
if(!vis[id]){
vis[id]=1;
q.push(id);
}
}
}
}
}
int main(){
scan(n);scan(m);scan(k);scan(s);
repi(1,n){
int cl;
scan(cl);
ins(n+cl,i);
}
repi(1,m){
int x,y;
scan(x);scan(y);
ins(x,y);
ins(y,x);
}
repi(1,k){
bfs(n+i);
}
repi(1,n){
sort(res[i].begin(),res[i].end());
ll ans=0;
repj(0,s-1){
ans+=res[i][j];
}
printf("%I64d",ans);
if(i!=n)printf(" ");
}
return 0;
}