这个题一看上去似乎很难,, 半联通子图根本就没听说过啊
但经过一段时间的思考之后似乎模型挺直接的、
但是其实,他就是问你一个选点最多的路径、 因为如果这些点如果不能能构成一条路径的话,不在路径上的点一定会以一个方向走入这条路径来 会导致相反方向的点不能到达
对于能互达的点,他们发出的任意一条边都可以作为路径,因此tarjan缩点 然后用拓扑序找路径即可
2A(第一遍MLE、)
码:
#include
#include
using namespace std;
#include
#include
#include
vectorv[100005];
queueq;
#define N 1000005
int dis,hou[N],xia[N],zhong[N],qi[N],d[N],s[N],sta[N],top,tot,cnt,jh[N],ru[N],f[N][3],pd[N],n,m,x,max1,max2;
void jian(int x,int y)
{
++tot;hou[tot]=xia[x];xia[x]=tot;zhong[tot]=y;qi[tot]=x;
}
void dfs(int o)
{
int i;
d[o]=++dis;
s[o]=dis;
sta[++top]=o;
for(i=xia[o];i!=-1;i=hou[i])
{
int nd=zhong[i];
//if(nd==fu)continue;
if(d[nd]==0)
{
dfs(nd);s[o]=min(s[o],s[nd]);
}else if(jh[nd]==0)s[o]=min(s[o],s[nd]);
}
if(s[o]==d[o])
{ ++cnt;
while(sta[top]!=o)
{
jh[sta[top]]=cnt;
v[cnt].push_back(sta[top]);
top--;
}
jh[sta[top]]=cnt;
v[cnt].push_back(sta[top]);
top--;
}
}
void dp()
{
int i,j;
for(i=1;i<=m;i++)
{
if(jh[qi[i]]!=jh[zhong[i]])ru[jh[zhong[i]]]++;
}
for(i=1;i<=cnt;i++)
{
if(ru[i]==0)q.push(i);
}
while(!q.empty())
{
int st=q.front();
f[st][0]+=v[st].size();
if(f[st][1]==0)f[st][1]=1;
q.pop();
for(i=0;i