zoukankan      html  css  js  c++  java
  • 【反向多源点同时BFS一个强连通图+类最短路题面】Fair-986C-Codeforce

    借鉴博客:https://www.cnblogs.com/zhangjiuding/p/9112273.html

    986-A. Fair

    /* 986-A-Fair,codeforce;
    大致题意:
          n个点,m个双向边; 一共K中食品,每个点只能提供1种;至少携带s种不同的食品,点u->v 需要花费d(u,v);d(u,v)是最短路u->v,的开销——开销等于该最短路的路径中的边数。每个点有一种食品,食品总的种类数不超过K个,求从每个点出发找至少种食品的最小开销。题目看着像是最短路,起个名字叫做类最短路题目!
    大致思路:
          直接进行裸的bfs,我的第一次的做法是枚举每个点作为单源点进行bfs的,这样时间复杂度最大为:(10^5)*(10^5)=顶点数*边数!尽管k只有100个,按理说找100个点不就够了-但可能出现极端情况,比如某几个点特别离散——很偏僻需要搜完整个图才可以找到,这样整个图的复杂度就上升很多了!
         怎么解决呢?再次审题找到突破口,k=100,然后就需要从突破口开始这k种食品的地方进行bfs,每次bfs某一种型号的食品——将该种型号食品的产地作为bfs的起点——更省时!复杂度为k*(10^5)=k *顶点数,及从每种食品开始bfs搜索完整个图存进d[][]中!
    */
     1 #define N 100008
     2 int a[N];
     3 vector<int>G[N];
     4 int d[N][108];//更新每个小镇到第i种食物的最小距离
     5 
     6 void init(int n){
     7     for(int i=0;i<=n;i++)
     8         G[i].resize(0);
     9 }
    10 bool vis[N];
    11 
    12 bool used[N];
    13 void bfs(int k,int n){
    14         queue<int>Q;
    15         for(int i=1;i<=k;i++){//暴力枚举第i种物品的源点,从每种物品的源点开始进行bfs!更省时!
    16             memset(used,false,sizeof(used));
    17             for(int j=1;j<=n;j++){
    18                 if(a[j]==i){
    19                     d[j][i]=0;
    20                     Q.push(j);
    21                     used[j]=true;
    22                 }
    23             }
    24             while(Q.size()>0){//进行BFS!
    25                 int x=Q.front();
    26                 Q.pop();
    27                 for(int t=0;t<(int)G[x].size();t++){
    28                     int v=G[x][t];
    29                     if(!used[v]){
    30                         d[v][i]=d[x][i]+1;//bfs记录节点
    31                         used[v]=true;
    32                         Q.push(v);
    33                     }
    34                 }
    35             }
    36         }
    37 }
    38 
    39 int main(){
    40     int n,m,k,s;
    41 
    42     while(scanf("%d%d%d%d",&n,&m,&k,&s)!=EOF){
    43         init(n);
    44         for(int i=1;i<=n;i++)
    45             scanf("%d",&a[i]);
    46         int x,y;
    47         for(int i=1;i<=m;i++){
    48             scanf("%d%d",&x,&y);
    49             G[x].push_back(y);
    50             G[y].push_back(x);
    51         }
    52         bfs(k,n);
    53 
    54        for(int i=1;i<=n;i++){
    55             sort(d[i]+1,d[i]+1+k);
    56             int ans=0;
    57             for(int j=1;j<=s;j++){
    58                 ans+=d[i][j];
    59             }
    60             printf("%d ",ans);
    61        }
    62        cout<<endl;
    63     }
    64     return 0;
    65 }
     
  • 相关阅读:
    hdu 1199 Color the Ball 离散线段树
    poj 2623 Sequence Median 堆的灵活运用
    hdu 2251 Dungeon Master bfs
    HDU 1166 敌兵布阵 线段树
    UVALive 4426 Blast the Enemy! 计算几何求重心
    UVALive 4425 Another Brick in the Wall 暴力
    UVALive 4423 String LD 暴力
    UVALive 4872 Underground Cables 最小生成树
    UVALive 4870 Roller Coaster 01背包
    UVALive 4869 Profits DP
  • 原文地址:https://www.cnblogs.com/zhazhaacmer/p/9122404.html
Copyright © 2011-2022 走看看