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 }