[CF] 986 A. Fair
阿新 • • 發佈:2018-07-06
就是 nim 連通圖 stream 無向連通圖 做的 clu gin printf
http://codeforces.com/problemset/problem/986/A
n個點的無向連通圖,每個點有一個屬性,求每個點到s個不同屬性點的最短距離
依稀記得那天晚上我和Menteur-Hxy探討這道題如何不可做的樣子
直觀想法當然是每個點出發bfs,找到s個就停止,但這最差是n^2的,不能接受!
解法是多源廣搜,註意到貨物種類非常小(<=100),所以可以求出每個點獲得每種貨物的最短距離。
做法是進行k次bfs,對於第i次,起點st是每個種類為i的點,廣搜的性質決定了她們的平行關系。
這樣就可以求出每種貨物到每個點的距離,換言之,就是每個點獲得每種貨物的代價(最小)
然後對於每個點,答案就是最小的s個啦
無向圖註意開兩倍邊
#include<algorithm> #include<iostream> #include<cstring> #include<cstdio> #include<vector> #include<queue> using namespace std; const int MAXN=100005; inline int rd(){ int ret=0,f=1;char c; while(c=getchar(),!isdigit(c))f=c==‘-‘?-1:1; while(isdigit(c))ret=ret*10+c-‘0‘,c=getchar(); return ret*f; } struct Edge{ int next,to; }e[MAXN<<1]; int ecnt,head[MAXN]; inline void add(int x,int y){ e[++ecnt].to = y; e[ecnt].next = head[x]; head[x] = ecnt; } int dis[MAXN][102],typ[MAXN]; //dis[i][j] - the minimum cost for town i to get the j-th goodsint n,m,k,s; queue<int> Q; void bfs(int x){ for(int i=1;i<=n;i++) if(typ[i]==x) Q.push(i),dis[i][x]=0; while(!Q.empty()){ int top=Q.front();Q.pop(); for(int i=head[top];i;i=e[i].next){ int v=e[i].to; if(dis[v][x]>dis[top][x]+1){ dis[v][x]=dis[top][x]+1; Q.push(v); } } } } void init(){ memset(dis,0x3f,sizeof(dis)); } vector<int> V; int main(){ n=rd();m=rd();k=rd();s=rd(); init(); for(int i=1;i<=n;i++) typ[i]=rd(); int x,y,w; for(int i=1;i<=m;i++){ x=rd();y=rd(); add(x,y);add(y,x); } for(int i=1;i<=k;i++) bfs(i); int ret=0; for(int i=1;i<=n;i++){ V.clear(); for(int j=1;j<=k;j++) V.push_back(dis[i][j]); sort(V.begin(),V.end()); ret=0; for(int j=0;j<s;j++) ret+=V[j]; printf("%d ",ret); } return 0; }
[CF] 986 A. Fair