“今日头条”杯2018年湖北省赛(网络赛):所有题目链接
可以提交的链接(不知道现在还能进不了,你还要有账号):传送门
Problem F. A-maze-ing
题目大意:很坑啊,当初读了半天题,没读懂是什么意思。
给你n个点,m条有向边,问你:其中一条路中包含点最多是多少。
思路:先用Trajan缩点,然后,深搜找出其中包含点最多的。
代码:
#include <cstdio>
#include <cstring>
#include <iostream>
#include<queue>
#include<math.h>
#include <string>
#include <algorithm>
#include<stack>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define inf 0x3f3f3f3f
#define PI acos(-1.0)
const int maxn=2*1e5+9;
int low[maxn],pre[maxn],sccno[maxn],sccinq[maxn],clock_pre,clock_low;//Trajan算法的
stack<int>s;
int vis[maxn],inq[maxn];//VIS记录缩点后入度为0的点,inq记录从该点开始所有路中包含最多的点是多少个。
int firs[maxn],first[maxn];//firs记录缩点前的边,first记录缩点后的边
struct node
{
int v,nex;
} edge[maxn],ed[maxn];
int N,tot;
void get(int u,int v)
{
edge[N]=(node)
{
v,firs[u]
};
firs[u]=N++;
}
void get1(int u,int v)
{
ed[tot]=(node)
{
v,first[u]
};
first[u]=tot++;
}
void init()//初始化
{
mem(low,0);
mem(pre,0);
clock_pre=clock_low=0;
mem(firs,-1);
mem(first,-1);
mem(vis,0);
mem(sccinq,0);
mem(sccno,0);
N=0;
mem(inq,0);
tot=0;
}
void Trajan(int x)//Trajan算法
{
pre[x]=low[x]=++clock_low;
s.push(x);
for(int i=firs[x]; ~i; i=edge[i].nex)
{
int v=edge[i].v;
if(!pre[v])
{
Trajan(v);
low[x]=min(low[v],low[x]);
}
else if(!sccno[v])
low[x]=min(low[x],pre[v]);
}
if(low[x]==pre[x])//重新建点
{
clock_pre++;
while(1)
{
int y=s.top();
s.pop();
sccno[y]=clock_pre;
sccinq[clock_pre]++;
if(y==x)
break;
}
}
}
void dfs(int s)//深搜
{
if(first[s]==-1)
{
inq[s]=sccinq[s];
return ;
}
for(int i=first[s]; ~i; i=ed[i].nex)
{
int v=ed[i].v;
if(!inq[v])
dfs(v);
inq[s]=max(inq[s],inq[v]+sccinq[s]);
}
return ;
}
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
init();
for(int i=0; i<m; i++)
{
int u,v;
scanf("%d%d",&u,&v);
get(u,v);
}
for(int i=1; i<=n; i++)//缩点
{
if(!pre[i])
Trajan(i);
}
for(int i=1; i<=n; i++)
{
for(int j=firs[i]; ~j; j=edge[j].nex)
{
int u=i,v=edge[j].v;
if(sccno[u]!=sccno[v])//重新建边
get1(sccno[u],sccno[v]),vis[sccno[v]]=1;
}
}
int ans=0;//记录答案
for(int i=1; i<=clock_pre; i++)
{
if(!vis[i])//找缩点后,入度为0的点,因为一定是从入度为零的点开始的
{
dfs(i);
ans=max(ans,inq[i]);
}
}
printf("%d\n",ans);
}
return 0;
}