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

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

    Time Limit: 30 Sec  Memory Limit: 162 MB
    Submit: 1986  Solved: 802
    [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。注意处理好大点间的重边。

    你问我写哪种dp?首推topo啊!记忆化什么的常数大的。。。(雾

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<algorithm>
     5 #include<stack>
     6 #include<queue>
     7 #include<cstring>
     8 #define PAU putchar(' ')
     9 #define ENT putchar('
    ')
    10 #define MSE(a,b) memset(a,b,sizeof(a))
    11 #define REN(x) for(ted*e=fch[x];e;e=e->nxt)
    12 #define REN2(x) for(ted*e=fch2[x];e;e=e->nxt)
    13 #define TIL(x) for(int i=1;i<=x;i++)
    14 #define ALL(x) for(int j=1;j<=x;j++)
    15 using namespace std;
    16 const int maxn=100000+10,maxm=1000000+10,inf=1e9;
    17 struct ted{int x,y;ted*nxt;}adj[maxm],adj2[maxm],*fch[maxn],*fch2[maxn],*ms=adj,*ms2=adj2;
    18 void add(int x,int y){*ms=(ted){x,y,fch[x]};fch[x]=ms++;return;}int in[maxn];
    19 void add2(int x,int y){*ms2=(ted){x,y,fch2[x]};fch2[x]=ms2++;in[y]++;return;}
    20 int dfn[maxn],low[maxn],beg[maxn],siz[maxn],scc,cz,f[maxn],g[maxn],vis[maxn],mod;bool ins[maxn];stack<int>S;
    21 void tarjan(int x){
    22     dfn[x]=low[x]=++cz;ins[x]=true;S.push(x);REN(x){int v=e->y;
    23         if(!dfn[v])tarjan(v),low[x]=min(low[x],low[v]);else if(ins[v])low[x]=min(low[x],dfn[v]);
    24     }if(low[x]==dfn[x]){scc++;int t;
    25         do beg[t=S.top()]=scc,ins[t]=false,S.pop(),siz[scc]++;while(t!=x);
    26     }return;
    27 }
    28 int n,m;
    29 void rebuild(){
    30     TIL(n)REN(i)if(beg[i]!=beg[e->y])add2(beg[i],beg[e->y]);return;
    31 }
    32 void topodp(){
    33     queue<int>Q;TIL(scc)if(!in[i])Q.push(i);TIL(scc)f[i]=siz[i],g[i]=1;
    34     while(!Q.empty()){
    35         int x=Q.front();Q.pop();REN2(x){int v=e->y;
    36             if(--in[v]==0)Q.push(v);
    37             if(vis[v]!=x){vis[v]=x;
    38                 if(f[x]+siz[v]>f[v])f[v]=f[x]+siz[v],g[v]=g[x];
    39                 else if(f[x]+siz[v]==f[v])(g[v]+=g[x])%=mod;
    40             }
    41         }
    42     }return;
    43 }
    44 inline int read(){
    45     int x=0;bool sig=true;char ch=getchar();
    46     for(;!isdigit(ch);ch=getchar())if(ch=='-')sig=false;
    47     for(;isdigit(ch);ch=getchar())x=10*x+ch-'0';return sig?x:-x;
    48 }
    49 inline void write(int x){
    50     if(x==0){putchar('0');return;}if(x<0)putchar('-'),x=-x;
    51     int len=0;static int buf[20];while(x)buf[len++]=x%10,x/=10;
    52     for(int i=len-1;i>=0;i--)putchar(buf[i]+'0');return;
    53 }
    54 int main(){
    55     n=read();m=read();mod=read();int x,y;
    56     TIL(m)x=read(),y=read(),add(x,y);
    57     TIL(n)if(!dfn[i])tarjan(i);rebuild();topodp();
    58     int mx=-inf,ans;
    59     TIL(scc){
    60         if(mx<f[i])mx=f[i],ans=g[i];
    61         else if(f[i]==mx)(ans+=g[i])%=mod;
    62     }write(mx);ENT;write(ans);
    63     return 0;
    64 }
  • 相关阅读:
    【python】利用python+tkinter做一个简单的智能电视遥控器
    【selenium】自动化测试中,元素无法点击定位等问题的解决:js的使用方法
    《Selenium 2自动化测试实战 基于Python语言》中发送最新邮件无内容问题的解决方法
    单线程代码事例
    死锁的实例
    大公司的Java面试题集
    xml文件有误
    android开发艺术探索
    Java 获取APK安装程序的包名
    内部类中class声明地方不同,效果不一样
  • 原文地址:https://www.cnblogs.com/chxer/p/4754138.html
Copyright © 2011-2022 走看看