洛谷P3916||图的遍历||反向建图||链式前向星||dfs

题目描述

给出 NN 个点, MM 条边的有向图,对于每个点 vv ,求 A(v)A(v) 表示从点 vv 出发,能到达的编号最大的点。

解题思路

看起来很简单的一道题,

但我依然调了一天,我还是太菜了

审题从一个点出发到达编号最远的点,其实可以反向优化为从最远的点出发可以到达哪些点,

这样每个点只需要遍历一次即可

然而以上是看题解才知道

我好菜啊

代码

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>

#define N 100010
using namespace std;

struct road{
    int u,m,v;
}ro[N];

int len=0,n,m;//n代表一共有几个城市
int first[N],last[N];
int vv[N],maxx[N],links[N];
void insert(int xx,int yy,int zz)
{
    len++;
    ro[len].u=xx;ro[len].m=yy;ro[len].v=zz;
    last[len]=first[xx];first[xx]=len;
}

void init()
{
    cin>>n>>m;
    for(int i=1;i<=m;i++)
    {
        int aa,bb;
        cin>>aa>>bb;
        insert(bb,aa,1);
        links[aa]++;
    }
}

void debug_output()
{
    for(int i=1;i<=len;i++)
    {
        cout<<ro[i].u<<' '<<ro[i].m<<' '<<ro[i].v<<' '<<first[i]<<' '<<last[i];
        cout<<endl;
    }
}
bool flag[N];

inline void judge(int k,int dd){    if(maxx[k]>dd)  maxx[k]=dd;}

void dfs(int Point,int st)
{
   if(maxx[Point])  return;
   maxx[Point]=st;
   for(int i=first[Point];i;i=last[i])//这个操作要记好,可以遍历单源点的每一条边
    if(!maxx[ro[i].m])  dfs(ro[i].m,st);
    return;

}

void output()
{
    for(int i=1;i<=n;i++)   cout<<maxx[i]<<' ';
    cout<<endl;
}
int main()
{
    init();
   for(int i=n;i>=1;i--)    dfs(i,i);
    output();
    return 0;
}

写的一如既往的长,,,

溜了溜了

猜你喜欢

转载自www.cnblogs.com/supersumax/p/9476206.html