华师一附中OI组

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 937|回复: 1
打印 上一主题 下一主题

P1137 旅行计划

[复制链接]

7

主题

27

帖子

91

积分

注册会员

Rank: 2

积分
91
跳转到指定楼层
楼主
发表于 2018-6-7 13:08:02 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 胡雨菲菲 于 2018-6-7 13:09 编辑

小明要去一个国家旅游。这个国家有 N 个城市,编号为 1 至 N ,并且有 M 条道路连接着,小明准备从其中一个城市出发,并只往东走到城市i停止。
所以他就需要选择最先到达的城市,并制定一条路线以城市i为终点,使得线路上除了第一个城市,每个城市都在路线前一个城市东面,并且满足这个前提下还希望游览的城市尽量多。
现在,你只知道每一条道路所连接的两个城市的相对位置关系,但并不知道所有城市具体的位置。现在对于所有的 i,都需要你为小明制定一条路线,并求出以城市 i 为终点最多能够游览多少个城市。

输入格式:

第 1 行为两个正整数 N,M 。
接下来 M 行,每行两个正整数 x,y ,表示了有一条连接城市 x 与城市 y 的道路,保证了城市 x 在城市 y 西面。
输出格式:
N 行,第 i 行包含一个正整数,表示以第 i 个城市为终点最多能游览多少个城市。
输入样例
5 6
1 2
1 3
2 3
2 4
3 4
2 5

输出样例
1
2
3
4
3



回复

使用道具 举报

7

主题

27

帖子

91

积分

注册会员

Rank: 2

积分
91
沙发
 楼主| 发表于 2018-6-7 13:10:27 | 只看该作者
  1. #include <cstdio>
  2. #include <algorithm>
  3. #include <queue>
  4. using namespace std;
  5. const int N = 100010;

  6. int topo[N];

  7. struct Edge {
  8.     int v, nex;
  9. }edge[N << 1]; int top;

  10. struct Poi {
  11.     int e, in, ans;
  12. }poi[N];

  13. inline void add(int x, int y) {
  14.     top++;
  15.     edge[top].v = y;
  16.     edge[top].nex = poi[x].e;
  17.     poi[x].e = top;
  18.     return;
  19. }

  20. void toposort(int n) {
  21.     queue<int> Q;
  22.     for(int i = 1; i <= n; i++) {
  23.         if(!poi[i].in) {
  24.             Q.push(i);
  25.         }
  26.     }
  27.     int t = 0;
  28.     while(!Q.empty()) {
  29.         int op = Q.front();
  30.         Q.pop();
  31.         topo[++t] = op;
  32.         for(int i = poi[op].e; i; i = edge[i].nex) {
  33.             int ed = edge[i].v;
  34.             poi[ed].in--;
  35.             if(!poi[ed].in) {
  36.                 Q.push(ed);
  37.             }
  38.         }
  39.     }
  40.     return;
  41. }

  42. int main() {
  43.     int m, n;
  44.     scanf("%d%d", &n, &m);
  45.     for(int i = 1, x, y; i <= m; i++) {
  46.         scanf("%d%d", &x, &y);
  47.         poi[x].in++;
  48.         add(y, x);
  49.     }
  50.     toposort(n);

  51.     for(int i = n; i >= 1; i--) {
  52.         int op = topo[i];
  53.         for(int i = poi[op].e; i; i = edge[i].nex) {
  54.             int ed = edge[i].v;
  55.             poi[op].ans = max(poi[op].ans, poi[ed].ans);
  56.         }
  57.         poi[op].ans++;
  58.     }

  59.     for(int i = 1; i <= n; i++) {
  60.         printf("%d\n", poi[i].ans);
  61.     }
  62.     return 0;
  63. }
复制代码
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|服务支持:DZ动力|华师一附中OI组  

GMT+8, 2024-11-2 20:32 , Processed in 0.102909 second(s), 24 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表