zoukankan      html  css  js  c++  java
  • Gym

    Gym - 102307G  Graduation 

    题意:xjl得修够n门课才能毕业,其中有些课是某门课的先行课,并且他精力有限,每学期最多只能修k门课,问xjl最少需要多少学期才能毕业。

    首先,正向的图是n对1的,一个点会受到多个点的限制,所以反向建图,这样每去掉一个点,所释放的点都是没有限制的。

    解法一:我们以原图中没有入度的点作为深度1,这样新图中没有人度的点就是最高深度,那么如果可以当前选择的点少于等于k个,直接便是取完这些点

    那么当多于k个时,根据我们反向的原理自然是让深度高的选取。

     1 #include<cstdio>
     2 #include<vector>
     3 #include<queue>
     4 #include<algorithm>
     5 using namespace std;
     6 const int N=1e4+11;
     7 struct Node{
     8     int id,dep;
     9     Node(){}
    10     Node(int id,int dep):id(id),dep(dep){}
    11     bool operator<(const Node& n1)const{
    12         return dep<n1.dep;
    13     }
    14 };
    15 int n,k,ne[N],ra[N];
    16 vector<int> vv[N];
    17 void dfs(int u){
    18     if(vv[u].size()==0){
    19         ra[u]=1;
    20         return ;
    21     }
    22     for(int i=0;i<(int)vv[u].size();i++){
    23         dfs(vv[u][i]);
    24         ra[u]=max(ra[u],ra[vv[u][i]]+1);
    25     }
    26 }
    27 int tp(){
    28     queue<int> q;
    29     priority_queue<Node> qq;
    30     for(int i=1;i<=n;i++) if(!ne[i]) qq.push(Node(i,ra[i]));
    31     int ans=0,cnt=0,u,v;
    32     while(!qq.empty()){
    33         ans++;
    34         cnt=0;
    35         while(!qq.empty()&&cnt<k){
    36             cnt++;
    37             q.push(qq.top().id);
    38             qq.pop();
    39         }
    40         while(!q.empty()){
    41             u=q.front();
    42             q.pop();
    43             for(int i=0;(int)i<vv[u].size();i++){
    44                 v=vv[u][i];
    45                 qq.push(Node(v,ra[v]));
    46             }
    47         }
    48     }
    49     return ans;
    50 }
    51 int main(){
    52     while(~scanf("%d%d",&n,&k)){
    53         for(int i=0;i<=n;i++) vv[i].clear();
    54         for(int i=1;i<=n;i++){
    55             scanf("%d",&ne[i]);
    56             if(!ne[i]) continue;
    57             vv[ne[i]].push_back(i);
    58         }
    59         for(int i=1;i<=n;i++) if(!ne[i]) dfs(i);
    60         printf("%d
    ",tp());
    61     }
    62     return 0;
    63 }
    nlogn

    解法二:每门课的最快能学的学期就取决于它的深度,当某个课被提前学到了 就说明在它的之前可选择的课少于k个,此时直接让那些课便作为一层。

     1 include<cstdio>
     2 #include<vector>
     3 #include<queue>
     4 #include<algorithm>
     5 using namespace std;
     6 const int N=1e4+11;
     7 int n,k,in[N],ne[N],ra[N];
     8 vector<int> vv[N]; 
     9 int tp(){
    10     queue<int> q;
    11     for(int i=1;i<=n;i++) if(!in[i]){
    12         ra[i]=1;
    13         q.push(i);
    14     }
    15     int ans=0,cnt=0,u,v;
    16     while(!q.empty()){
    17         u=q.front();
    18         q.pop();
    19         cnt++;
    20         if(cnt==1) ans++;
    21         if(cnt==k) cnt=0;
    22         if(ra[u]>ans) ans++,cnt=1;
    23         for(int i=0;i<(int)vv[u].size();i++){
    24             v=vv[u][i];
    25             ra[v]=max(ra[v],ra[u]+1);
    26             in[v]--;
    27             if(!in[v]) q.push(v);
    28         }
    29     }
    30     return ans;
    31 }
    32 int main(){
    33     while(~scanf("%d%d",&n,&k)){
    34         for(int i=0;i<=n;i++){
    35             in[i]=ra[i]=0;
    36             vv[i].clear();
    37         }
    38         for(int i=1;i<=n;i++){
    39             scanf("%d",&ne[i]);
    40             if(!ne[i]) continue;
    41             in[i]++;
    42             vv[ne[i]].push_back(i);
    43         }
    44         printf("%d
    ",tp());
    45     }
    46     return 0;
    47 }
    48 /*
    49 4 2
    50 4 4 4 0
    51 */
    n
  • 相关阅读:
    vs2015解决fopen、fscanf 要求替换为fopen_s、fscanf_s的办法
    ThinkPHP5.1的公共函数
    Linux禁止ping
    2019.10.17 上科大虞晶怡教授
    Minimax极大极小算法、Alpha-Beta Pruning剪枝算法
    Apache24服务无法启动,发生服务特定错误1.
    LaTeX小白安装超详细步骤(WIndows系统)||相信我看这个安装就够啦!
    Java中Comparator比较器的使用
    当我看到别人二战想法,退缩的时候,我的感受
    2019.12.3 学英语的心得;学习学习
  • 原文地址:https://www.cnblogs.com/LMCC1108/p/11672321.html
Copyright © 2011-2022 走看看