原题

题目大意及思路
给定图,判断输入的序列是否是拓扑序列,若不是,则记入答案数组中输出;
这个题主要参考判断和输出拓扑序列时利用入度为0的性质。
通过遍历某一结点时将除前面出现过的结点之外的以它出发的边的终点的入度减1,到最后查看入度数组是否全部为0,若否,则不是拓扑序列。
代码
#include<iostream>
#include<vector>
#include<queue>
using namespace std;
const int maxn=1009;
vector<int> Graph[maxn];
vector<int> ingree;
int main(){
int n,m,k;
cin>>n>>m;
ingree.resize(n+1);
while(m--){
int start,end;
cin>>start>>end;
Graph[start].push_back(end);
ingree[end]++;
}
cin>>k;
vector<int> ans;
for(int i=0;i<k;i++){
vector<int> cpingree(n+1);
int data;
bool vis[n+1]={false};
for(int j=1;j<ingree.size();j++) cpingree[j]=ingree[j];
for(int j=1;j<=n;j++){
cin>>data;
vis[data]=true;
for(int t=0;t<Graph[data].size();t++){
if(!vis[Graph[data][t]]) cpingree[Graph[data][t]]--;
}
}
for(int j=1;j<=n;j++){
if(cpingree[j]){
ans.push_back(i);
break;
}
}
}
for(int i=0;i<ans.size();i++) printf("%d%s",ans[i],i==ans.size()-1?"\n":" ");
}
运行截图

收获
这个题主要是利用了拓扑序列输出和判断的想法:找到入度为0的结点加入队列中,将以它出发的边的终点的入度加一。
那么我们逆向来看的话,如果把前面的点屏蔽,只让在它后面的点的入度减一,若非全0,则不是。
- 面对一些问题时,找到这种数据结构的特性来解决问题才是最有效最不浪费的方法。
1万+



被折叠的 条评论
为什么被折叠?



