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

2016-06-21

读一下题目,发现环内肯定在一个半联通子图内,于是先tarjan缩点,然后就是找这个图的最长链及数目。拓扑一下即可。

注意注意  此题一定要将边进行判重。

 

  1 #include<iostream>
  2 #include<cstring>
  3 #include<cstdio>
  4 #include<algorithm>
  5 #include<queue>
  6 #include<cstdlib>
  7 #include<map>
  8 #define ll long long
  9 #define M 2000009
 10 using namespace std;
 11 ll read()
 12 {
 13     char ch=getchar();
 14     ll x=0,f=1;
 15     for(;ch<'0'||ch>'9';ch=getchar())
 16       if(ch=='-')
 17         f=-1;
 18     for(;ch>='0'&&ch<='9';ch=getchar())
 19       x=x*10+ch-'0';
 20     return x*f;
 21 }
 22 int du[M],dfn[M],low[M],K,n,m,tot,head[M],next[M],u[M],belong[M],cnt,T,q[M],sum,he[M];
 23 bool f[M];
 24 int ss;
 25 struct data
 26 {
 27     int d,s;
 28 }a[M],qq[M];
 29 bool cmp(data a1,data a2)
 30 {
 31     if(a1.s==a2.s)
 32       return a1.d<a2.d;
 33     return a1.s<a2.s;
 34 }
 35 void jia(int a1,int a2)
 36 {
 37     next[++cnt]=head[a1];
 38     head[a1]=cnt;
 39     u[cnt]=a2;
 40 }
 41 void tarjin(int x)
 42 {
 43     dfn[x]=low[x]=++T;
 44     q[++tot]=x;
 45     f[x]=1;
 46     for(int i=head[x];i;i=next[i])
 47       if(!dfn[u[i]])
 48         {
 49             tarjin(u[i]);
 50             low[x]=min(low[x],low[u[i]]);
 51         }
 52       else  if(f[u[i]])
 53              low[x]=min(low[x],dfn[u[i]]);
 54     if(low[x]==dfn[x])
 55       {
 56           sum++;
 57           for(;q[tot]!=x;tot--)
 58             {
 59                 he[sum]++;
 60                 belong[q[tot]]=sum;
 61                 f[q[tot]]=0;
 62             }
 63         he[sum]++;
 64         belong[x]=sum;
 65         f[x]=0;
 66         tot--;
 67       }
 68 }
 69 int main()
 70 {
 71     n=read();
 72     m=read();
 73     K=read();
 74     for(int i=1;i<=m;i++)
 75       {
 76           int a=read(),b=read();
 77           jia(a,b);
 78       }
 79     sum=n;
 80     for(int i=1;i<=n;i++)
 81       if(!dfn[i])
 82         tarjin(i);
 83     for(int i=1;i<=n;i++)
 84       for(int j=head[i];j;j=next[j])
 85           {
 86             qq[++ss].s=belong[i];
 87             qq[ss].d=belong[u[j]];
 88         }
 89     sort(qq+1,qq+ss+1,cmp);
 90     for(int i=1;i<=ss;i++)
 91       if(qq[i].s!=qq[i].d&&(qq[i].s!=qq[i-1].s||qq[i].d!=qq[i-1].d))
 92         {
 93           jia(qq[i].s,qq[i].d);
 94           du[qq[i].d]++;
 95         }
 96     int h=0,t=0;
 97     for(int i=n+1;i<=sum;i++)
 98       if(!du[i])
 99         {
100             q[++t]=i;
101             a[i].d=he[i];
102             a[i].s=1;
103         }
104     for(;h<t;)
105       {
106           int p=q[++h];
107           for(int i=head[p];i;i=next[i])
108             {
109                 du[u[i]]--;
110                 if(!du[u[i]])
111                   q[++t]=u[i];
112                 if(a[u[i]].d==a[p].d+he[u[i]])
113                   a[u[i]].s=(a[u[i]].s+a[p].s)%K;
114             if(a[u[i]].d<a[p].d+he[u[i]])
115                   {
116                     a[u[i]].d=a[p].d+he[u[i]];
117                 a[u[i]].s=a[p].s;
118               }
119           }
120       }
121     int mx=0,mxx=0;
122     for(int i=n+1;i<=sum;i++)
123       {
124         if(a[i].d==mx)
125           mxx=(mxx+a[i].s)%K;
126         if(a[i].d>mx)
127           {
128               mx=a[i].d;
129               mxx=a[i].s;
130           }
131       }
132     printf("%d\n%d",mx,mxx);
133     return 0;
134 }

 

posted @ 2016-06-21 15:25  xiw5  阅读(...)  评论(...编辑  收藏