- 题解
车站分级
- @ 2024-10-13 16:41:57
#include<bits/stdc++.h>
using namespace std;
/*
最坏情况下有1000趟火车,每趟1000个点,500个停靠,500个不停靠站
不停站的点 和 停站的点 都链接一条边: 500*500*1000 = 2.5 * 10^8
*/
const int N = 2010, M = 1e6 + 20; //一趟车次需要一个虚拟点,每次最多1000条边
int n, m;
int e[M], ne[M], w[M], h[N], idx;
int dist[N];
bool st[N];
int q[N], d[N]; //d数组是统计每个点的入度的个数
int res;
void add(int a, int b, int c)
{
e[idx] = b;
w[idx] = c;
ne[idx] = h[a];
h[a] = idx ++;
d[b] ++;
}
void topsort()
{
int hh = 0, tt = -1;
for(int i = 1; i <= n + m; i++)
{
if(!d[i]) q[++tt] = i;
}
while(hh <= tt) {
int t = q[hh++];
for(int i = h[t]; i != -1; i = ne[i])
{
int j = e[i];
if(--d[j] == 0)
q[++tt] = j;
}
}
}
int main()
{
cin >> n >> m;
memset(h, -1, sizeof h);
for(int i = 1; i <= m; i++)
{
memset(st, 0, sizeof st);
int cnt;
cin >> cnt;
int start = n, end = 1;
while(cnt --)
{
int stop;
cin >> stop;
start = min(start, stop);
end = max(end, stop);
st[stop] = true;
}
int v = i + n; //虚拟点,是从n+1开始编号
for(int j = start; j <= end; j++)
if(st[j]) add(v, j, 1);
else add(j, v, 0);
}
topsort();
for(int i = 1; i <= n; i++) dist[i] = 1;
for(int i = 0; i < n + m; i++) // n+m个点
{
int t = q[i];
cout << t << ":";
for(int k = h[t]; k != -1; k = ne[k])
{
int j = e[k];
dist[j] = max(dist[j], dist[t] + w[k]);
cout << "j=" << j << " " << dist[j] << endl;
}
cout << "-------------" << endl;
}
// for(int i = 1; i <= n + m; i++)
// cout << dist[i] << " ";
// cout << endl;
for(int i = 1; i <= n; i++)
res = max(res, dist[i]);
cout << res << endl;
return 0;
}
0 条评论
目前还没有评论...