洛谷 P1983 车站分级

方法:

拓扑排序

 

分级:停靠的站级别>未停靠站的级别

            从未停靠的站向已经停靠的站加边  然后进行拓扑排序

 

这个题最好加个读入优化,不优化只能的90分

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 int dp[1005];//dp[]表示级别高低 (大于关系)
  4 int h[1005],ind[1005];//h[]表示第一条边;ind[]表示入度 
  5 int vis[1005][1005];//两点之间是否有边 
  6 int aa[1005],v[1005];//aa是输入车站的编号,v标记停靠的站点 
  7 int m,n,t;//m是有多少列车,n是有多少车站,t是加边计数器 
  8 
  9 struct edge{
 10     int to;
 11     int next;
 12 }car[500005];
 13 
 14 void add(int from ,int to ){
 15      
 16      car[++t].next=h[from];
 17      car[t].to=to;
 18      h[from]=t;
 19      
 20 }
 21 
 22 inline ll read(){
 23     int sign = 1;
 24     char c = getchar();
 25     while(c > '9' || c < '0'){
 26         if(c == '-') sign = -1;
 27         c = getchar();
 28     }
 29     ll x = 0;
 30     while(c <= '9' && c >= '0'){ 
 31         x = x * 10 + c - '0';
 32         c = getchar();
 33     }
 34     return x * sign;
 35 }
 36 
 37 int main(){
 38     int ans=0;
 39     int a,b;
 40     
 41     n=read();
 42     m=read();
 43     
 44     
 45     for(int ii=1;ii<=m;ii++){
 46         
 47         a=read();//输入此列车有几个停靠站 
 48         
 49         memset(v,0,sizeof(v));
 50         
 51         
 52         for(int j=1;j<=a;j++)
 53         {
 54           aa[j]=read();
 55           v[aa[j]]=1; //标记停靠的站点 
 56         }    
 57         
 58         for(int i=aa[1];i<=aa[a];i++)//这趟火车经过的所有站点 
 59         {
 60             if(!v[i])  //站点没有停靠 
 61             {
 62                 for(int j=aa[1];j<=aa[a];j++)
 63                 {
 64                 
 65                 if(v[j]&&!vis[i][j])//从未停靠向停靠站点加边 
 66                    {
 67                    add(i,j);
 68                    vis[i][j]=1; 
 69                    ind[j]++;
 70                    }
 71                 
 72                 }
 73              
 74              } 
 75         }
 76         
 77     }
 78     
 79     queue<int> q;
 80     //topo排序 
 81     for(int i=1;i<=n;i++){
 82         if(!ind[i])
 83         q.push(i),dp[i]=1;
 84     }
 85     
 86     while(!q.empty()){
 87         int u=q.front();  
 88             q.pop();
 89         for(int i = h[u] ; i ; i = car[i].next){
 90             int v=car[i].to;
 91                 dp[v]=max(dp[v],dp[u]+1);
 92                 ans=max(ans,dp[v]);
 93                 if(!(--ind[v])) q.push(v);
 94         }
 95     }
 96     
 97     cout<<ans<<endl;
 98 
 99     return 0;
100 } 

 

转载于:https://www.cnblogs.com/nvwang123/p/10506151.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值