首先我们需要确定起点,即最先到达的城市,因为我们希望经过的城市数量最多,因此考虑从最西边出发,即入度为0的顶点出发,到这里容易想到使用拓扑排序解答
对于每个顶点,我们定义一个ans数组记录以i点为终点时经过的最大城市数,不难发现
每个点的答案是它所有前驱节点的答案加1
跑完一遍拓扑排序,答案也就出来了
#include<iostream> #include<vector> #include<stack> using namespace std; const int MAX=1e5+10; int n,m,s; vector<int>mapp[MAX];//邻接表存图 int arr[MAX];//记录每个顶点的入度 int ans[MAX];//记录到达城市i最多可游览多少个城市 void fun(){ //先找到入度为0的点 入栈 int len=0; stack<int>stk; for(int i=1;i<=n;i++){ if(arr[i]==0){ stk.push(i); ans[i]=1;//入度为0的点为终点则为1 } } while(!stk.empty()){ int cur=stk.top(); stk.pop(); int sizee=mapp[cur].size(); for(int i=0;i<sizee;i++){//遍历cur临接点 int v=mapp[cur][i]; ans[v]=max(ans[v],ans[cur]+1);//临界点的答案 if(--arr[v]==0){ stk.push(v);//如果去除cur点后其临界点入度为0 } } } } int main(){ cin>>n>>m; for(int i=1;i<=m;i++){ int x,y; cin>>x>>y; mapp[x].push_back(y);//无权有向图 arr[y]++; } //由于希望游览的城市尽量多,因此我们考虑从最西边出发,即无入度的节点出发 fun(); for(int i=1;i<=n;i++){ cout<<ans[i]<<endl; } return 0; }
旅行计划(拓扑排序)
最新推荐文章于 2024-11-02 14:41:43 发布