CF D. Fair(思維+DFS)
阿新 • • 發佈:2018-06-03
problem 進行 分析 can 技術 sin dfs ack tor
http://codeforces.com/contest/987/problem/D
題目大概:
給出一個n個城鎮m條邊的圖,給出每個城鎮擁有的特產(可能多個城鎮有相同特產)。有k種不同特產。
要求每個城鎮需要其他城鎮運輸特產到自己的城鎮,每個城鎮必須擁有s種特產,那麽在城鎮滿足s種特產後,需要的最短路徑是多長,最短路指的是特產運輸過來走過的邊的數量。
分析:
一開始以為是道水題,因為我只要對每個點都進行一次DFS,那問題就很簡單了,但是。。。細想下,這其實是不行的,因為會TLE. 那現在我們來轉化下思維,城市太多了,可是特產的種類很少,所以!!!!我們算出每種特產到每個城市的最短距離,然後把所有到i城鎮的特產的最短路 排序,取前s個就是i點的最短路徑了。
#include <bits/stdc++.h> using namespace std; const int maxn=1e5+5; const int INF=0x3f3f3f3f; int e[maxn]; int vis[maxn];///標記 int lis[maxn][120];///記錄 vector<int>F[120];///每種特產到每個城市 vector<int>G[maxn];///建圖 struct poin { int x,d; }; int ans=0; int s; void bfs(int x) { queue<poin>Q;View Code///x種特產的開始城市 for(int i=0;i<F[x].size();i++) { int v=F[x][i]; poin q; q.x=v;q.d=0; Q.push(q); } ///x種特產去到的城市 while(!Q.empty()) { poin u=Q.front();Q.pop(); ///u.x城市到x特產的最短距離 lis[u.x][x]=min(u.d,lis[u.x][x]); for(int i=0;i<G[u.x].size();i++) {int v=G[u.x][i]; if(vis[v])continue; vis[v]=1; poin q; q.x=v; q.d=u.d+1; Q.push(q); } } } int main() { int n,m,k; scanf("%d%d%d%d",&n,&m,&k,&s); for(int i=1;i<=n;i++) { scanf("%d",&e[i]); F[e[i]].push_back(i);///e[i]產品在多少城市 } int u,v; for(int i=1;i<=m;i++) { scanf("%d%d",&u,&v); G[u].push_back(v);///無向圖 G[v].push_back(u); } memset(lis,0x3f3f3f3f,sizeof(lis)); for(int i=1;i<=k;i++) { memset(vis,0,sizeof(vis)); bfs(i);///對每種特產DFS } for(int i=1;i<=n;i++) { sort(lis[i]+1,lis[i]+k+1);///排序 long long sum=0; ///i城市擁有的s種特產的最短距離 for(int j=1;j<=s;j++) { sum+=lis[i][j]; } printf("%I64d ",sum); } return 0; }
CF D. Fair(思維+DFS)