每个点访问一次,这个A值就是最优的,因为之后如果再访问到这个结点那么答案肯定没当前大了
![](https://img-blog.csdnimg.cn/direct/e034cfeef8a24be0940b8b0500de5a65.png)
AC代码:用学习的模板写
#include<algorithm>
#include<iostream>
#include<cstring>
#include<queue>
#include<cmath>
using namespace std;
const int N = 100010;
int h[N],e[N],ne[N],idx;
int n,m;
int path[N];
int q[N];
void add(int a,int b){
e[idx] = b;
ne[idx] = h[a];
h[a] = idx ++;
return;
}
void bfs(int i){
if(!path[i])//如果之前较大的点还没有到达过该点
{
int hh = 0,tt = -1;
path[i] = i;//则最大的就是自身
q[++tt] = i;//将该点放入队列
while(hh <= tt){
int x = q[hh++];//取队头
for(int j=h[x];j!=-1;j = ne[j]){//找该点能到达的点,如果有的点还没更新过,则将它的path值更新为i
int temp = e[j]; //取出来点的值,如果还没有被搜索过
if(!path[temp]){
q[++tt] = temp;
path[temp] = i;
}
}
}
}
return;
}
int main()
{
scanf("%d%d",&n,&m);
memset(h,-1,sizeof(h));
for(int i=0;i<m;i++)
{
int a,b;
scanf("%d%d",&a,&b);
add(b,a);//反向加边
}
//反向搜索 ,将答案记录在ans里
for(int i=n;i>0;i--){
bfs(i);
}
for(int i=1;i<=n;i++)
printf("%d ",path[i]);
return 0;
}
结果:
![](https://img-blog.csdnimg.cn/direct/97a89baf4d3a417286c9306bdff2de5a.png)
尝试代码1:得了10分,但我感觉写的挺对的啊......
#include<algorithm>
#include<iostream>
#include<cstring>
#include<queue>
#include<cmath>
using namespace std;
const int N = 100010;
int n,m;
int h[N*2],e[N*2],ne[N*2],idx;
bool st[N];
int path[N] = {-1};
int maxx=-1;
int t=1;
void add(int a,int b){
e[idx] = b;
ne[idx] = h[a];
h[a] = idx ++;
return;
}
void dfs(int u){//点的编号
st[u] = true;
for(int i=h[u];i!= -1;i = ne[i]){
int j = e[i];
if(!st[j]) {
maxx = max(maxx,j);
dfs(j);
return;//!!!!void性函数,要及时返回return
}
}
path[t++] = maxx;
return;
}
int main()
{
memset(h,-1,sizeof(h));
cin>>n>>m;
for(int i=0;i<m;i++){
int a,b;
cin>>a>>b;
add(a,b);//有向图
}
for(int i=1;i<=n;i++){
maxx = i;
memset(st,false,sizeof(st));
if(h[i] == -1) {
path[t++] = i;
}
else dfs(i);
}
for(int i=1;i<=n;i++){
cout<<path[i]<<" ";
}
return 0;
}
参考网络代码2:反向建边,从最大的数值倒推,看大值点能到达哪些点。
#include<algorithm>
#include<iostream>
#include<cstring>
#include<queue>
#include<cmath>
using namespace std;
const int N = 100010;
int h[N],ne[N],e[N],idx;
int n,m;
int ans[N];
queue<int> q;
void add(int a,int b){
e[idx] = b;
ne[idx] = h[a];
h[a] = idx ++;
return;
}
int main()
{
scanf("%d%d",&n,&m);
memset(h,-1,sizeof(h));
for(int i=0;i<m;i++)
{
int a,b;
scanf("%d%d",&a,&b);
add(b,a);//反向加边
}
//从值大的点开始倒推
for(int i=n;i>0;i--){
if(!ans[i])//
{
ans[i] = i;
q.push(i);
while(!q.empty()){
int x = q.front();
q.pop();
for(int j=h[x];j!=-1;j=ne[j]){
if(!ans[e[j]]){
q.push(e[j]);
ans[e[j]] = i;
}
}
}
}
}
for(int i=1;i<=n;i++)
printf("%d ",ans[i]);
return 0;
}
结果:
![](https://img-blog.csdnimg.cn/direct/abd3d6aa9e814d46ba005651b10e4c8f.png)