zoukankan      html  css  js  c++  java
  • ZOJ 3795:Grouping(缩点+最长路)

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5303

    题意:有n个人m条边,每条边有一个u,v,代表u的年龄大于等于v,现在要将这n个人分成x个组,组内的人的年龄不能够直接或者间接比较,问最少可以分成多少组。

    思路:一开始没看清题意,直接拓扑排序做了。后来听师兄说会有环,年龄大于等于,如果有环代表这里面的年龄相等,那么环里面的人都是每个人一组,缩完点之后那个点的长度就是点的人数,然后用DP最长路做。

     1 #include <cstdio>
     2 #include <algorithm>
     3 #include <iostream>
     4 #include <cstring>
     5 #include <string>
     6 #include <cmath>
     7 #include <queue>
     8 #include <vector>
     9 #include <map>
    10 #include <set>
    11 #include <stack>
    12 using namespace std;
    13 #define INF 0x3f3f3f3f
    14 #define N 100010
    15 struct Edge {
    16     int v, nxt;
    17 } edge[N*3], edg[N*3];
    18 int cnt[N], dp[N], head[N], hea[N], tott, tot, tim, vis[N], deg[N], dfn[N], low[N], belong[N], num;
    19 stack<int> sta;
    20 
    21 void Add(int u, int v) {
    22     edge[tot].v = v; edge[tot].nxt = head[u]; head[u] = tot++;
    23 }
    24 
    25 void add(int u, int v) {
    26     edg[tott].v = v; edg[tott].nxt = hea[u]; hea[u] = tott++;
    27 }
    28 
    29 void tarjan(int u) {
    30     dfn[u] = low[u] = ++tim;
    31     sta.push(u); vis[u] = 1;
    32     for(int i = head[u]; ~i; i = edge[i].nxt) {
    33         Edge &e = edge[i];
    34         if(!dfn[e.v]) {
    35             tarjan(e.v);
    36             if(low[e.v] < low[u]) low[u] = low[e.v];
    37         } else if(vis[e.v] && dfn[e.v] < low[u]) low[u] = dfn[e.v];
    38     }
    39     if(low[u] == dfn[u]) {
    40         ++num; int v = -1;
    41         cnt[num] = 0;
    42         while(v != u) {
    43             v = sta.top(); sta.pop();
    44             belong[v] = num;
    45             cnt[num]++;
    46             vis[v] = 0;
    47         }
    48     }
    49 }
    50 
    51 int DFS(int u) {
    52     if(dp[u]) return dp[u];
    53     int ans = cnt[u];
    54     for(int i = hea[u]; ~i; i = edg[i].nxt) {
    55         int v = edg[i].v;
    56         ans = max(ans, DFS(v) + cnt[u]);
    57     }
    58     return dp[u] = ans;
    59 }
    60 
    61 int main() {
    62     int n, m;
    63     while(~scanf("%d%d", &n, &m)) {
    64         memset(head, -1, sizeof(head));
    65         memset(hea, -1, sizeof(hea));
    66         memset(dfn, 0, sizeof(dfn));
    67         memset(dp, 0, sizeof(dp));
    68         tot = num = tott = tim = 0;
    69         int u, v;
    70         for(int i = 0; i < m; i++) {
    71             scanf("%d%d", &u, &v);
    72             Add(u, v);
    73         }
    74         for(int i = 1; i <= n; i++)
    75             if(!dfn[i]) tarjan(i);
    76         for(int u = 1; u <= n; u++) {
    77             for(int i = head[u]; ~i; i = edge[i].nxt) {
    78                 int v = edge[i].v;
    79                 if(belong[u] != belong[v]) {
    80                     add(belong[u], belong[v]);
    81                 }
    82             }
    83         }
    84         int ans = 0;
    85         for(int i = 1; i <= num; i++)
    86             ans = max(ans, DFS(i));
    87         printf("%d
    ", ans);
    88     }
    89     return 0;
    90 }
  • 相关阅读:
    js获取当前网页的源码
    jquery实现点击图片全屏查看功能
    html查看大图、js查看大图
    【后端】SSM(Spring + SpringMVC + Mybatis)框架整合(二)
    【macOS】免费使用正版 Paragon NTFS for Mac(非破解)
    【后端】SSM(Spring + SpringMVC + Mybatis)框架整合(一)
    c# 自动生成N个随机数和为1
    分布式事务的解决方案
    【JUC】一些线程基础
    【工具】apng图像判定调研
  • 原文地址:https://www.cnblogs.com/fightfordream/p/6275069.html
Copyright © 2011-2022 走看看