Tarjan-bzoj1093: [ZJOI2007]最大半连通子图
http://www.lydsy.com/JudgeOnline/problem.php?id=1093
先太监缩点,之后就变成了拓扑图;
第一问就是问最长链嘛,这个大家基本上全在用拓扑排序去搞;
其实dfs就好了……………………..
然后,求数量,这个直接在dfs里面乱搞就好了;
然后这个取模,如果你dp的话没问题;
反正dfs的时候要比较大小的;
这个时候就用高精度就好了;
就是再开一个数组存x取了几次莫;
然后比较就乱搞;
但是会重边;
其实我们只要dfs到一个点x时;
我们去搜索其子节点的时候不去重复;
那么直接再搞一个数组就好了;
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#define Ll long long
using namespace std;
struct cs{
Ll to,next;
}a[1000001];//f[i]是i点的最优结果;ff[i]是结果的次数%X;fff[i]是结果取了几次%;
Ll head[100001],tt[100001],lin[100001],low[100001],c[1000001][2],q[100001],f[100001],ff[100001],fff[100001],sum[100001];
bool in[100001];
Ll x,y,z,n,m,ans,ll,Ans,ANS,t,X,nn;
void init(Ll x,Ll y){
a[++ll].to=y;
a[ll].next=head[x];
head[x]=ll;
}
void dfs(Ll x){
low[x]=tt[x]=++t; in[x]=1; q[++q[0]]=x;
for(int k=head[x];k;k=a[k].next){
if(!tt[a[k].to])dfs(a[k].to);
if(in[a[k].to])low[x]=min(low[x],low[a[k].to]);
}
if(low[x]==tt[x]){
nn++;
while(1){
lin[q[q[0]]]=nn;
in[q[q[0]]]=0;
sum[nn]++;
q[0]--;
if(q[q[0]+1]==x)break;
}
}
}
void find(Ll x){
in[x]=1; t++;//这个tt代表循环次数
for(int k=head[x];k;k=a[k].next){
if(!in[a[k].to])find(a[k].to);
//其实我的程序有鬼的,但是不知为什么AC了
//我的t在同一层会变的啊!!!!!;
if(tt[a[k].to]==t)continue;else tt[a[k].to]=t;//这个就是去重边,t++就免去了memset;
if(f[a[k].to]==f[x]){
ff[x]+= ff[a[k].to];
fff[x]+=fff[a[k].to];//类似高精度
fff[x]+=ff[x]/X;
ff[x]%=X;
}
if(f[a[k].to]>f[x])f[x]=f[a[k].to],ff[x]=ff[a[k].to],fff[x]=fff[a[k].to];
}
if(f[x])f[x]+=sum[x];else f[x]=sum[x],ff[x]=1,fff[x]=0;
if(f[x]==ans){
Ans+=ff[x];
ANS+=fff[x];
ANS+=Ans/X;
Ans%=X;
}
if(f[x]>ans)ans=f[x],Ans=ff[x],ANS=fff[x];
}
int main()
{
scanf("%lld%lld%lld",&n,&m,&X);
for(int i=1;i<=m;i++){
scanf("%lld%lld",&c[i][0],&c[i][1]);
init(c[i][0],c[i][1]);
}
for(int i=1;i<=n;i++)if(!tt[i])dfs(i);//tarjan
memset(head,0,sizeof head);ll=0;
for(int i=1;i<=m;i++){
x=lin[c[i][0]];y=lin[c[i][1]];
if(x==y)continue;
init(x,y);
}
memset(in,0,sizeof in);
memset(tt,0,sizeof tt);t=0;
for(int i=1;i<=nn;i++)if(!in[i])find(i);
printf("%lld\n%lld",ans,Ans);
}
其实这个程序问题很大;
首先根本不用fff数组呵呵呵;
呵呵呵呵呵呵………………..
ANS答案根本无关系
然后那个t还有漏洞(数据水)
其实那个t要另开变量存起来……..
但是思路是对的
那就不改了.
呵呵呵呵呵呵呵呵呵呵呵呵呵呵呵呵呵呵
感谢jzqjzq指出我的错误;本垃圾;还需大家指点;