上来是一道拓扑排序的题,什么是拓扑排序呢?
总的来说核心点有三个:找到入度为0的节点、移除入度为0的节点、根据最后结果数组的大小是否等于节点数判断有向图中是否有环。
代码如下:
#include<iostream>
#include<vector>
#include<queue>
#include<unordered_map>
using namespace std;
int main(){
int n,m,s,t;
cin>>n>>m;
vector<int> res;
unordered_map<int,vector<int>> mp;
vector<int> inDegrees(n,0);
while(m--){
cin>>s>>t;
inDegrees[t]++;
mp[s].push_back(t);
}
queue<int> q;
for(int i=0;i<n;++i){
if(inDegrees[i]==0)q.push(i);
}
while(!q.empty()){
int cur=q.front();
q.pop();
res.push_back(cur);
vector<int> file=mp[cur];
if(file.size()){
for(int i=0;i<file.size();++i){
inDegrees[file[i]]--;
if(inDegrees[file[i]]==0)q.push(file[i]);
}
}
}
if(res.size()==n){
for(int i=0;i<n-1;++i){
cout<<res[i]<<" ";
}
cout<<res.back()<<endl;
}
else cout<<-1<<endl;
return 0;
}
47. 参加科学大会(第六期模拟笔试) (kamacoder.com)
开始进入我们的最短路径问题了,今天我们接触的是经典的迪杰斯特拉算法。
可以看到我们的迪杰斯特拉算法在思路上来说和之前的最小生成树的prim算法类似,说白了本质上都是贪心算法的思维底座。
#include<iostream>
#include<vector>
#include<climits>
using namespace std;
int main(){
int n,m,s,e,v;
cin>>n>>m;
vector<vector<int>> grid(n+1,vector<int>(n+1,INT_MAX));
while(m--){
cin>>s>>e>>v;
grid[s][e]=v;
}
vector<int> minDist(n+1,INT_MAX);
vector<bool> visited(n+1,false);
minDist[1]=0;
for(int i=1;i<=n;++i){
int minval=INT_MAX,cur=1;
for(int t=1;t<=n;++t){
if(!visited[t]&&minDist[t]<minval){
minval=minDist[t];
cur=t;
}
}
visited[cur]=true;
for(int t=1;t<=n;++t){
if(!visited[t]&&grid[cur][t]!=INT_MAX&&minDist[t]>minDist[cur]+grid[cur][t]){
minDist[t]=minDist[cur]+grid[cur][t];
}
}
}
if(minDist[n]==INT_MAX)cout<<-1<<endl;
else cout<<minDist[n]<<endl;
}