代码随想录算法训练营第五十八天|KamaCoder117. 软件构建,KamaCoder47. 参加科学大会

KamaCoder117. 软件构建

题目链接:117. 软件构建
文章讲解:代码随想录
视频讲解:图论:拓扑排序,这次我悟了!_哔哩哔哩_bilibili

思路:拓扑排序的思路是定义一个indegree数组存放所有点的入度,定义一个umap存放一个点和他能连接到的所有节点,我们在读入数据的时候,给每个t的入度+1,同时把umap中s对应的vector加入t。首先我们选择全部入度为0的节点作为初始节点,加入到que中,然后进行以下操作,把que中队列头的节点弹出,加入到结果集中,并保存他在umap中对应的vector作为file,也就是他所连接的节点,然后我们将他连接的所有节点的入度-1,然后看看有没有入度为0的节点了,如果有就加入到que中,如此训话往复。最后输出结果的时候,如果result的总数不是n就说明出现了死锁,所以输出-1,如果等于n就一个一个输出结果。

代码:

#include<iostream>
#include<vector>
#include<queue>
#include<unordered_map>

using namespace std;

int main(){
    int n,m;
    cin>>n>>m;
    vector<int>indegree(n,0);
    unordered_map<int,vector<int>>umap;
    vector<int>result;
    int s,t;
    while(m--){
        cin>>s>>t;
        indegree[t]++;
        umap[s].push_back(t);
    }
    queue<int>que;
    for(int i=0;i<n;i++){
        if(indegree[i]==0){
            que.push(i);
        }
    }
    while(!que.empty()){
        int cur=que.front();
        que.pop();
        result.push_back(cur);
        vector<int>files=umap[cur];
        if(!files.empty()){
            for(int i=0;i<files.size();i++){
                indegree[files[i]]--;
                if(indegree[files[i]]==0){
                    que.push(files[i]);
                }
            }
        }
    }
    if(result.size()==n){
        for(int i=0;i<n-1;i++){
            cout<<result[i]<<" ";
        }
        cout<<result[n-1]<<endl;
    }
    else{
        cout<<-1<<endl;
    }
}

KamaCoder47. 参加科学大会

题目链接:47. 参加科学大会(第六期模拟笔试)
文章讲解:代码随想录
视频讲解:图论:最短路算法之Dijkstra (朴素版) | 迪杰斯特拉算法_哔哩哔哩_bilibili

思路:这道题的算法和prim的代码很像,同样是分为三步,第一步是选取离出发点最近且未被访问过的节点记为cur,第二步是标记该节点cur已被访问,第三步是更新所有未被访问的节点经过cur的访问的距离,如果变近了就更新,更新的话是取原来的值mindist[k]和经过cur的值mindist[cur]+grid[cur][k]的更小者。最后看mindist[end]是否有被更新过,如果没被更新,依然是INT_MAX的话就输出-1,否则输出mindist[end]。

代码:

#include<iostream>
#include<vector>
#include<climits>
using namespace std;
int main(){
    int n,m;
    cin>>n>>m;
    vector<vector<int>>grid(n+1,vector<int>(n+1,INT_MAX));
    int p1,p2,val;
    while(m--){
        cin>>p1>>p2>>val;
        grid[p1][p2]=val;
    }
    int start=1;
    int end=n;
    vector<int>mindist(n+1,INT_MAX);
    vector<bool>visited(n+1,false);
    mindist[start]=false;
    for(int i=1;i<=n;i++){
        int minval=INT_MAX;
        int cur=1;
        for(int j=1;j<=n;j++){
            if(!visited[j]&&mindist[j]<minval){
                minval=mindist[j];
                cur=j;
            }
        }
        visited[cur]=true;
        for(int k=1;k<=n;k++){
            if(!visited[k]&&grid[cur][k]!=INT_MAX&&mindist[cur]+grid[cur][k]<mindist[k]){
                mindist[k]=mindist[cur]+grid[cur][k];
            }
        }
    }
    if(mindist[end]==INT_MAX){
        cout<<-1<<endl;
    }
    else{
        cout<<mindist[end]<<endl;
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值