1. 程式人生 > >CF D. Fair(思維+DFS)

CF D. Fair(思維+DFS)

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;
    
///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; }
View Code

CF D. Fair(思維+DFS)