您的位置:首页 > 其它

强连通分量,DAG上的最长路,记忆化搜索(最大团,UVA 11324)

2017-02-09 17:57 393 查看
一点手误,搞WA了。。。

代码

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn = 1010;
const int maxm = 50010;

int pre[maxn],lowlink[maxn],cnt[maxn],sccno[maxn],dfs_clock,scc_cnt;
vector<int>G[maxn],GG[maxn];
stack<int>s;
void dfs(int u)
{
pre[u]=lowlink[u]=++dfs_clock;
s.push(u);
for(unsigned int i=0;i<G[u].size();i++)
{
int v=G[u][i];
if(!pre[v])
{
dfs(v);
lowlink[u]=min(lowlink[u],lowlink[v]);
}
else if(!sccno[v]) lowlink[u]=min(lowlink[u],pre[v]);
}
if(pre[u]==lowlink[u])
{
scc_cnt++;
for(;;)
{
cnt[scc_cnt]++;
int x=s.top();s.pop();
sccno[x]=scc_cnt;
if(x==u) break;
}
}
}

void find_scc(int n)
{
dfs_clock=scc_cnt=0;
rep(i,1,n) if(!pre[i]) dfs(i);
}

int u[maxm],v[maxm];
int d[maxn];
set<pair<int,int> >vis;

int dp(int cur)
{
int& ans=d[cur];
if(ans!=-1) return ans;
ans=0;
for(unsigned int i=0;i<GG[cur].size();i++)
{
int v=GG[cur][i];
ans=max(ans,dp(v));
}
return ans=ans+cnt[cur];
}

int main()
{
int T,n,m;
scanf("%d",&T);
while(T--)
{
scanf("%d %d",&n,&m);
rep(i,1,n)
{
G[i].clear();
GG[i].clear();
pre[i]=lowlink[i]=sccno[i]=cnt[i]=0;
d[i]=-1;
}
rep(i,1,m)
{
scanf("%d %d",&u[i],&v[i]);
G[u[i]].push_back(v[i]);
}
find_scc(n);
vis.clear();
rep(i,1,m) if(sccno[u[i]]!=sccno[v[i]])
{
if(!vis.count(make_pair(sccno[u[i]],sccno[v[i]])))
{
vis.insert(make_pair(sccno[u[i]],sccno[v[i]]));
GG[sccno[u[i]]].push_back(sccno[v[i]]);
}
}
int ans=0;
rep(i,1,scc_cnt)
ans=max(ans,dp(i));
printf("%d\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: