zoukankan      html  css  js  c++  java
  • bzoj 1093 [ZJOI2007]最大半连通子图(scc+DP)

    1093: [ZJOI2007]最大半连通子图

    Time Limit: 30 Sec  Memory Limit: 162 MB
    Submit: 2286  Solved: 897
    [Submit][Status][Discuss]

    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。

    Source

    【思路】

           强连通分量+拓扑排序+DP

           求scc,锁点。则问题转化为求DAG上的最长路,在拓扑序上进行DP即可。 

        需要注意的是重新构图的时候会有重边,为了防止重复计数需要特别处理一下。

    【代码】

      1 #include<cstdio>
      2 #include<stack>
      3 #include<queue>
      4 #include<vector>
      5 #include<cstring>
      6 #include<iostream>
      7 using namespace std;
      8 
      9 const int maxn =  100000+10;
     10 
     11 vector<int> g[maxn],G[maxn];
     12 int pre[maxn],lowlink[maxn],sccno[maxn],scccnt,dfsclock;
     13 stack<int> S;
     14 
     15 int dfs(int u) {
     16     pre[u]=lowlink[u]=++dfsclock;
     17     S.push(u);
     18     for(int i=0;i<g[u].size();i++) {
     19         int v=g[u][i];
     20         if(!pre[v]) {
     21             dfs(v);
     22             lowlink[u]=min(lowlink[u],lowlink[v]);
     23         }
     24         else if(!sccno[v]) {
     25             lowlink[u]=min(lowlink[u],pre[v]);
     26         }
     27     }
     28     if(lowlink[u]==pre[u]) {
     29         ++scccnt;
     30         for(;;) {
     31             int x=S.top() ; S.pop();
     32             sccno[x]=scccnt;
     33             if(x==u) break;
     34         }
     35     }
     36 }
     37 void findscc(int n) {
     38     memset(pre,0,sizeof(pre));
     39     memset(sccno,0,sizeof(sccno));
     40     dfsclock=scccnt=0;
     41     for(int i=0;i<n;i++)
     42         if(!pre[i]) dfs(i);
     43 }
     44 
     45 int n,m,MOD;
     46 int d[maxn],cnt[maxn];
     47 
     48 int val[maxn],in[maxn];
     49 void build() {
     50     for(int i=0;i<n;i++) {
     51         val[sccno[i]]++;
     52         for(int j=0;j<g[i].size();j++) {
     53             int v=g[i][j];   
     54             if(sccno[i]==sccno[v]) continue;
     55             in[sccno[v]]++;
     56             G[sccno[i]].push_back(sccno[v]);
     57         }
     58     }
     59 }
     60 void solve() {
     61     queue<int> q;
     62     int vis[maxn];
     63     for(int i=1;i<=scccnt;i++) if(!in[i]) {
     64         d[i]=val[i] , cnt[i]=1;
     65         q.push(i);
     66     }
     67     while(!q.empty()) {
     68         int u=q.front(); q.pop();
     69         for(int i=0;i<G[u].size();i++) {
     70             int v=G[u][i];
     71             if(!(--in[v])) q.push(v);
     72             if(vis[v]!=u) {                        //重新构图后有重边 防止重复计数 
     73                 if(d[v]<d[u]+val[v]) {
     74                     d[v]=d[u]+val[v]; cnt[v]=cnt[u];
     75                 }
     76                 else if(d[v]==d[u]+val[v])
     77                     cnt[v]=(cnt[v]+cnt[u])%MOD;
     78             }
     79             vis[v]=u;
     80         }
     81     }
     82 }
     83 
     84 int main() {
     85     scanf("%d%d%d",&n,&m,&MOD);
     86     int u,v;
     87     while(m--) {
     88         scanf("%d%d",&u,&v);
     89         u-- , v--;
     90         g[u].push_back(v);
     91     }
     92     findscc(n);
     93     build();
     94     solve();
     95     int ans=0,ansnum=0;
     96     for(int i=1;i<=scccnt;i++)
     97         if(ans<d[i])  ans=d[i] , ansnum=cnt[i];
     98         else if(ans==d[i]) ansnum=(ansnum+cnt[i])%MOD;
     99     printf("%d
    %d",ans,ansnum);
    100     return 0;
    101 }
  • 相关阅读:
    nethogs 实时查看进程使用流量情况。
    Bash 使用技巧
    Linux源代码编译安装tree命令
    【字体区别】Serif和Sans Serif
    MySQL数据库恢复的经历。
    Linux常用命令
    关于一机多区的可行性分析。
    记一次node节点异常排查
    kube-prometheus部署
    认证、授权与准入控制
  • 原文地址:https://www.cnblogs.com/lidaxin/p/5103593.html
Copyright © 2011-2022 走看看