P1983 车站分级 思维+拓扑排序

很久以前的一道暑假集训的题,忘了补。

感觉就是思维建图,加拓扑排序。

未停靠的火车站,必然比停靠的火车站等级低,就可以以此来建边,此处注意用vis来维护一下,一个起点和终点只建立一条边,因为不这样的话会重复建边。

虽然重复建边拓扑排序的时候,统计入度,更新入度的时候完全不影响结果,因为这个重复的点和入度都统计了,也都会在拓扑的删去,答案依然正确。

但是重复建边vector会弄的很大,导致MLE(我debug好久才发现MLE的原因)。洛谷上只能get到80分,加了vis就100了。

主要是思维吧,未经过的点向经过点建边,拓扑找每个点所属的层数,最后统计答案即可。

代码如下:

 1 #include <bits/stdc++.h>
 2 #define debug(x) cout << #x << ": " << x << endl
 3 using namespace std;
 4 typedef long long ll;
 5 
 6 const int MAXN=1024;
 7 const int INF=0x3f3f3f3f;
 8 const int MOD=1e9+7;
 9 
10 int in[MAXN],lv[MAXN],stay[MAXN];
11 bool is[MAXN];
12 bool vis[MAXN][MAXN];
13 vector<int> to[MAXN];
14 int n,m;
15 queue<int> q;
16 
17 void topsort()
18 {
19     for(int i=1;i<=n;++i)
20     {
21         if(!in[i])
22         {
23             q.push(i);
24             lv[i]=1;
25         }
26     }
27     while(!q.empty())
28     {
29         int u=q.front();q.pop();
30         for(auto v:to[u])
31         {
32             in[v]--;
33             if(in[v]==0)
34             {
35                 q.push(v);
36                 lv[v]=lv[u]+1;
37             }
38         }
39     }
40 }
41 
42 int main()
43 {
44     ios::sync_with_stdio(false);
45     cin.tie(0);
46     cin>>n>>m;
47     while(m--)
48     {
49         int s;
50         cin>>s;
51         memset(is,0,sizeof(is));
52         for(int i=1;i<=s;++i)
53         {
54             cin>>stay[i];
55             is[stay[i]]=true;
56         }
57         for(int i=stay[1];i<=stay[s];++i)
58         {
59             if(!is[i])
60             {
61                 //debug(i);
62                 for(int j=1;j<=s;++j)
63                 {
64                     int u=stay[j];
65                     if(!vis[u][i])
66                     {
67                         vis[u][i]=1;
68                         to[i].push_back(u);
69                         in[u]++;
70                     }
71                 }
72             }
73         }
74     }
75    // for(int i=1;i<=n;++i)
76      //   debug(in[i]);
77     topsort();
78     int ans=0;
79     for(int i=1;i<=n;++i)
80     {
81        // debug(lv[i]);
82         ans=max(ans,lv[i]);
83     }
84     cout<<ans<<endl;
85     return 0;
86 }

猜你喜欢

转载自www.cnblogs.com/Zzqf/p/11914770.html