zoukankan      html  css  js  c++  java
  • 【HDOJ】4297 One and One Story

    综合性很强的题目。
    存在环,可以用tarjan处理,然后需要求LCA。并查集+RMQ可以搞。
    非常不错的题目。

      1 /* 4297 */
      2 #include <iostream>
      3 #include <sstream>
      4 #include <string>
      5 #include <map>
      6 #include <queue>
      7 #include <set>
      8 #include <stack>
      9 #include <vector>
     10 #include <deque>
     11 #include <algorithm>
     12 #include <cstdio>
     13 #include <cmath>
     14 #include <ctime>
     15 #include <cstring>
     16 #include <climits>
     17 #include <cctype>
     18 #include <cassert>
     19 #include <functional>
     20 #include <iterator>
     21 #include <iomanip>
     22 using namespace std;
     23 //#pragma comment(linker,"/STACK:102400000,1024000")
     24 
     25 #define sti                set<int>
     26 #define stpii            set<pair<int, int> >
     27 #define mpii            map<int,int>
     28 #define vi                vector<int>
     29 #define pii                pair<int,int>
     30 #define vpii            vector<pair<int,int> >
     31 #define rep(i, a, n)     for (int i=a;i<n;++i)
     32 #define per(i, a, n)     for (int i=n-1;i>=a;--i)
     33 #define clr                clear
     34 #define pb                 push_back
     35 #define mp                 make_pair
     36 #define fir                first
     37 #define sec                second
     38 #define all(x)             (x).begin(),(x).end()
     39 #define SZ(x)             ((int)(x).size())
     40 #define lson            l, mid, rt<<1
     41 #define rson            mid+1, r, rt<<1|1
     42 
     43 typedef struct {
     44     int v, nxt;
     45 } edge_t;
     46 
     47 const int maxn = 500005;
     48 // input
     49 int link[maxn], link2[maxn];
     50 
     51 // tarjan
     52 int low[maxn], pre[maxn], bn[maxn], C[maxn];
     53 int S[maxn], top;
     54 int dfs_clock, block;
     55 
     56 // LCA
     57 int head[maxn], l;
     58 edge_t E[maxn<<1];
     59 int deg[maxn], beg[maxn];
     60 int deep[maxn], V[maxn<<1], D[maxn<<1];
     61 
     62 // RMQ
     63 int dp[maxn<<1][20];
     64 
     65 int dis[maxn];
     66 int fa[maxn];
     67 int n;
     68 
     69 
     70 int find(int x) {
     71     if (x == fa[x])
     72         return x;
     73     
     74     int tmp = fa[x];
     75     fa[x] = find(fa[x]);
     76     dis[x] += dis[tmp];
     77     return fa[x];
     78 }
     79 
     80 void tarjan(int u) {
     81     S[top++] = u;
     82     pre[u] = low[u] = ++dfs_clock;
     83     
     84     int v = link[u];
     85     
     86     if (!pre[v]) {
     87         tarjan(v);
     88         low[u] = min(low[u], low[v]);
     89     } else if (!bn[v]) {
     90         low[u] = min(low[u], pre[v]);
     91     }
     92     
     93     if (pre[u] == low[u]) {
     94         ++block;
     95         C[block] = 0;
     96         do {
     97             bn[S[--top]] = block;
     98             ++C[block];
     99         } while (S[top] != u);
    100     }
    101 }
    102 
    103 void addEdge(int u, int v) {
    104     E[l].v = v;
    105     E[l].nxt = head[u];
    106     head[u] = l++;
    107 }
    108 
    109 void dfs(int u, int d) {
    110     deep[u] = d;
    111     V[++top] = u;
    112     D[top] = d;
    113     beg[u] = top;
    114     
    115     int v, k;
    116     
    117     for (k=head[u]; k!=-1; k=E[k].nxt) {
    118         v = E[k].v;
    119         if (link2[v] == -1) {
    120             link2[v] = link2[u];
    121         }
    122         dfs(v, d+1);
    123         V[++top] = u;
    124         D[top] = d;
    125     }
    126 }
    127 
    128 void RMQ_init() {
    129     int len = top;
    130     int i, j, k;
    131     
    132     for (i=1; i<=len; ++i)
    133         dp[i][0] = i;
    134     for (j=1; (1<<j)<=len; ++j) {
    135         for (i=1; i+(1<<j)-1<=len; ++i) {
    136             if (D[dp[i][j-1]] < D[dp[i+(1<<(j-1))][j-1]])
    137                 dp[i][j] = dp[i][j-1];
    138             else
    139                 dp[i][j] = dp[i+(1<<(j-1))][j-1];
    140         }
    141     }
    142 }
    143 
    144 int RMQ(int l, int r) {
    145     if (l > r)
    146         swap(l, r);
    147     
    148     int k = 0;
    149     
    150     while ((1<<(k+1)) <= r-l+1)
    151         ++k;
    152     
    153     if (D[dp[l][k]] < D[dp[r-(1<<k)+1][k]])
    154         return V[dp[l][k]];
    155     else
    156         return V[dp[r-(1<<k)+1][k]];
    157 }
    158 
    159 void init() {
    160     dfs_clock = top = block = 0;
    161     memset(pre, 0, sizeof(pre));
    162     memset(bn, 0, sizeof(bn));
    163     
    164     rep(i, 1, n+1) {
    165         if (!pre[i])
    166             tarjan(i);
    167     }
    168     
    169     l = 0;
    170     memset(head, -1, sizeof(head));
    171     memset(link2, -1, sizeof(link2));
    172     memset(deg, 0, sizeof(deg));
    173     memset(dis, 0, sizeof(dis));
    174     rep(i, 1, n+1) {
    175         int bv = bn[i];
    176         int bu = bn[link[i]];
    177         if (bu == bv) {
    178             int fx = find(link[i]);
    179             int fy = find(i);
    180             if (fx != fy) {
    181                 fa[fy] = fx;
    182                 dis[fy] = dis[link[i]] + 1;
    183             }
    184         } else {
    185             addEdge(bu, bv);
    186             ++deg[bv];
    187             if (C[bu] > 1) {
    188                 link2[bv] = link[i];
    189             }
    190         }
    191     }
    192     
    193     rep(i, 1, block+1) {
    194         if (deg[i] == 0)
    195             addEdge(0, i);
    196     }
    197     
    198     
    199     // init RMQ
    200     top = 0;
    201     dfs(0, 0);
    202     RMQ_init();
    203 }
    204 
    205 void solve(int u, int v) {
    206     if (u == v) {
    207         puts("0 0");
    208         return ;
    209     }
    210     
    211     int bu = bn[u];
    212     int bv = bn[v];
    213     int lca = RMQ(beg[bu], beg[bv]);
    214     
    215     
    216     #ifndef ONLINE_JUDGE
    217         printf("bu = %d, bv = %d, lca = %d
    ", bu, bv, lca);
    218     #endif
    219     
    220     if (lca == 0) {
    221         puts("-1 -1");
    222         return ;
    223     }
    224     
    225     if (C[lca] == 1) {
    226         printf("%d %d
    ", deep[bu]-deep[lca], deep[bv]-deep[lca]);
    227         return ;
    228     }
    229     
    230     int u2v, v2u;
    231     int du, dv;
    232     
    233     if (bu == bv) {
    234         du = dv = 0;
    235         find(u);
    236         find(v);
    237         
    238         if (dis[u] < dis[v]) {
    239             u2v = C[bu] + dis[u] - dis[v];
    240             v2u = dis[v] - dis[u];
    241         } else {
    242             u2v = dis[u] - dis[v];
    243             v2u = C[bv] + dis[v] - dis[u];
    244         }
    245         
    246     } else {
    247         
    248         du = deep[bu] - deep[lca];
    249         dv = deep[bv] - deep[lca];
    250         
    251         int uu = link2[bu]==-1 ? u:link2[bu];
    252         int vv = link2[bv]==-1 ? v:link2[bv];
    253         
    254         find(uu);
    255         find(vv);
    256         
    257         #ifndef ONLINE_JUDGE
    258             // printf("uu=%d, duu=%d, vv=%d, dvv=%d
    ", uu, dis[uu], vv, dis[vv]);
    259         #endif
    260         if (dis[uu] < dis[vv]) {
    261             u2v = C[lca] + dis[uu] - dis[vv];
    262             v2u = dis[vv] - dis[uu];
    263         } else {
    264             u2v = dis[uu] - dis[vv];
    265             v2u = C[lca] + dis[vv] - dis[uu];
    266         }
    267     }
    268     
    269     #ifndef ONLINE_JUDGE
    270         printf("du=%d, dv=%d, u2v=%d, v2u=%d
    ", du,dv,u2v,v2u);
    271     #endif
    272     if (max(u2v+du, dv) < max(v2u+dv, du)) {
    273         printf("%d %d
    ", u2v+du, dv);
    274     } else if (max(u2v+du, dv) > max(v2u+dv, du)) {
    275         printf("%d %d
    ", du, v2u+dv);
    276     } else {
    277         if (min(u2v+du, dv) < min(v2u+dv, du)) {
    278             printf("%d %d
    ", u2v+du, dv);
    279         } else if (min(u2v+du, dv) > min(v2u+dv, du)) {
    280             printf("%d %d
    ", du, v2u+dv);
    281         } else {
    282             printf("%d %d
    ", max(u2v+du, dv), min(u2v+du, dv));
    283         }
    284     }
    285 }
    286 
    287 int main() {
    288     ios::sync_with_stdio(false);
    289     #ifndef ONLINE_JUDGE
    290         freopen("data.in", "r", stdin);
    291         freopen("data.out", "w", stdout);
    292     #endif
    293     
    294     int q;
    295     int u, v;
    296     
    297     while (scanf("%d %d", &n, &q)!=EOF) {
    298         rep(i, 1, n+1) {
    299             fa[i] = i;
    300             scanf("%d", &link[i]);
    301         }
    302         init();
    303         while (q--) {
    304             scanf("%d %d", &u, &v);
    305             solve(u, v);
    306         }
    307     }
    308     
    309     #ifndef ONLINE_JUDGE
    310         printf("time = %d.
    ", (int)clock());
    311     #endif
    312     
    313     return 0;
    314 }

     数据生成器。

     1 from random import randint, shuffle
     2 import shutil
     3 import string
     4 
     5 
     6 def GenDataIn():
     7     with open("data.in", "w") as fout:
     8         t = 10
     9         bound = 5*10**5
    10         for tt in xrange(t):
    11             n = randint(bound/10, bound)
    12             q = randint(bound/10, bound)
    13             fout.write("%d %d
    " % (n, q))
    14             dataList = []
    15             for i in xrange(n):
    16                 x = randint(1, n)
    17                 dataList.append(x)
    18             fout.write(" ".join(map(str, dataList)) + "
    ")
    19             for i in xrange(q):
    20                 u = randint(1, n)
    21                 v = randint(1, n)
    22                 fout.write("%d %d
    " % (u, v))
    23                 
    24 def MovDataIn():
    25     desFileName = "F:eclipse_prjworkspacehdojdata.in"
    26     shutil.copyfile("data.in", desFileName)
    27 
    28     
    29 if __name__ == "__main__":
    30     GenDataIn()
    31     MovDataIn()
  • 相关阅读:
    HDU 6143 Killer Names【dp递推】【好题】【思维题】【阅读题】
    HDU 6143 Killer Names【dp递推】【好题】【思维题】【阅读题】
    POJ 3974 Palindrome【manacher】【模板题】【模板】
    POJ 3974 Palindrome【manacher】【模板题】【模板】
    HDU 6127 Hard challenge【计算机几何】【思维题】
    HDU 6127 Hard challenge【计算机几何】【思维题】
    HDU 6129 Just do it【杨辉三角】【思维题】【好题】
    HDU 6129 Just do it【杨辉三角】【思维题】【好题】
    HDU 3037 Saving Beans【Lucas定理】【模板题】【模板】【组合数取余】
    8.Math 对象
  • 原文地址:https://www.cnblogs.com/bombe1013/p/5171347.html
Copyright © 2011-2022 走看看