这道题很简单…一上来直接DFS
#include <iostream>
#include <algorithm>
#include <queue>
#include <cstring>
#define Max 100005
using namespace std;
vector<int > Graph[Max];
int flag[Max];
void dfs(int v,int Max_v);
int res;
int main()
{
int n,m,v1,v2;
cin>>n>>m;
for(int i=1;i<=m;i++)
{
cin>>v1>>v2;
Graph[v1].push_back(v2);
}
memset(flag, false, sizeof(flag));
int v;
for(int i=1;i<=n;i++)
{
memset(flag, false, sizeof(flag));
res=i;
dfs(i,n);
cout<<res<<" ";
}
return 0;
}
void dfs(int v,int Max_v)
{
flag[v]=true;
for(int i=0;i<Graph[v].size();i++)
{
if(!flag[Graph[v][i]])
{
res=max(res,Graph[v][i]);
if(res==Max_v) //剪枝
{
return ;
}
dfs(Graph[v][i],Max_v);
}
}
}
只有60分,后面四个全部超时,一口老血…
不过也可以理解,10^3不超时才怪呢
所以我们要想其他办法
我们可以反着建图,然后从后面往前
n----->1
当顶点为v时,我们用dfs从v开始遍历这个图,看看能到达那些点,然后把能到达的点标记,并把到达的那个点他的所能达到最大点设置为i
下面是AC代码~
#include <iostream>
#include <algorithm>
#include <queue>
#include <cstring>
#define Max 100005
using namespace std;
vector<int > Graph[Max];
int flag[Max];
void dfs(int v,int t);
int a[Max];
int main()
{
int n,m,v1,v2;
cin>>n>>m;
for(int i=1;i<=m;i++)
{
cin>>v1>>v2;
Graph[v2].push_back(v1);
}
memset(flag, false, sizeof(flag));
int v;
for(int i=n;i;i--)
{
if(!flag[i])
{
dfs(i,i);
}
}
for(int i=1;i<=n;i++)
{
cout<<a[i]<<" ";
}
return 0;
}
void dfs(int v,int t)
{
flag[v]=true;
a[v]=t; //遍历所有当前能达到的点
for(int i=0;i<Graph[v].size();i++)
{
if(!flag[Graph[v][i]])
{
dfs(Graph[v][i],t);
}
}
}