zoukankan      html  css  js  c++  java
  • bzoj1093: [ZJOI2007]最大半连通子图

    Description

    Input

    第一行包含两个整数N,M,X。N,M分别表示图G的点数与边数,X的意义如上文所述。接下来M行,每行两个正整数a, b,表示一条有向边(a, b)。图中的每个点将编号为1,2,3…N,保证输入中同一个(a,b)不会出现两次。

    Output

    应包含两行,第一行包含一个整数K。第二行包含整数C Mod X.

    Sample Input

    6 6 20070603
    1 2
    2 1
    1 3
    2 4
    5 6
    6 4

    Sample Output

    3
    3

    HINT

    对于100%的数据, N ≤100000, M ≤1000000;对于100%的数据, X ≤10^8。

     
    题解:
    先进行缩点,得到一张DAG,然后最大半连通子图就是这个DAG包含点数最多的链,dp一下即可
    code:
     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<algorithm>
     6 #define maxn 100005
     7 #define maxm 1000005
     8 using namespace std;
     9 char ch;
    10 bool ok;
    11 void read(int &x){
    12     for (ok=0,ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') ok=1;
    13     for (x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());
    14     if (ok) x=-x;
    15 }
    16 int n,m,mod,a,b;
    17 int idx,dfn[maxn],low[maxn],top,stack[maxn],cnt,belong[maxn],sum[maxn];
    18 bool in[maxn];
    19 int num;
    20 struct Edge{
    21     int u,v;
    22     inline bool operator==(Edge b){return u==b.u&&v==b.v;}
    23 }edge[maxm];
    24 inline bool cmp(Edge a,Edge b){
    25     if (a.u==b.u) return a.v<b.v;
    26     return a.u<b.u;
    27 }
    28 int head,tail,list[maxn],f[maxn],g[maxn],deg[maxn];
    29 struct Graph{
    30     int tot,now[maxn],pre[maxm],son[maxm];
    31     void put(int a,int b){pre[++tot]=now[a],now[a]=tot,son[tot]=b;}
    32     void dfs(int u){
    33         dfn[u]=low[u]=++idx,stack[++top]=u,in[u]=1;
    34         for (int p=now[u],v=son[p];p;p=pre[p],v=son[p])
    35             if (!dfn[v]) dfs(v),low[u]=min(low[u],low[v]);
    36             else if (in[v]) low[u]=min(low[u],dfn[v]);
    37         if (dfn[u]==low[u]){
    38             int v; ++cnt;
    39             do{v=stack[top--],in[v]=0,belong[v]=cnt,sum[cnt]++;}while(v!=u);
    40         }
    41     }
    42     void get(){
    43         for (int u=1;u<=n;u++)
    44             for (int p=now[u],v=son[p];p;p=pre[p],v=son[p])
    45                 if (belong[u]!=belong[v]) edge[++num]=(Edge){belong[u],belong[v]};
    46         sort(edge+1,edge+num+1,cmp),num=unique(edge+1,edge+num+1)-edge-1;
    47     }
    48     void calc(){
    49         head=0,tail=0;
    50         for (int i=1;i<=cnt;i++) if (!deg[i]) list[++tail]=i,g[i]=1;
    51         while (head<tail){
    52             int u=list[++head];
    53             f[u]+=sum[u];
    54             for (int p=now[u],v=son[p];p;p=pre[p],v=son[p]){
    55                 if (f[v]<f[u]) f[v]=f[u],g[v]=g[u];
    56                 else if (f[v]==f[u]) g[v]+=g[u],g[v]%=mod;
    57                 deg[v]--;
    58                 if (!deg[v]) list[++tail]=v;
    59             }
    60         }
    61         int ans1=0,ans2=0;
    62         for (int i=1;i<=cnt;i++) ans1=max(ans1,f[i]);
    63         printf("%d
    ",ans1);
    64         for (int i=1;i<=cnt;i++) if (ans1==f[i]) ans2+=g[i],ans2%=mod;
    65         printf("%d
    ",ans2);
    66     }
    67 }G1,G2;
    68 int main(){
    69     read(n),read(m),read(mod);
    70     for (int i=1;i<=m;i++) read(a),read(b),G1.put(a,b);
    71     for (int i=1;i<=n;i++) if (!dfn[i]) G1.dfs(i);
    72     G1.get();
    73     for (int i=1;i<=num;i++) G2.put(edge[i].u,edge[i].v),deg[edge[i].v]++;
    74     G2.calc();
    75     return 0;
    76 }
  • 相关阅读:
    吴恩达老师机器学习课程学习--课时三
    吴恩达老师机器学习课程学习--课时二
    Linux查看大文件日志
    maven导出工程pom文件中依赖的jar包
    通过生成HFile导入HBase
    hbase之RPC详解
    HBase最佳实践-读性能优化策略
    HBaseRegionServer宕机数据恢复
    HBase–RegionServer宕机恢复原理
    为什么不建议在 HBase 中使用过多的列族
  • 原文地址:https://www.cnblogs.com/chenyushuo/p/5101009.html
Copyright © 2011-2022 走看看